diff --git a/Selector.CLI/Program.cs b/Selector.CLI/Program.cs
index 01d4c8f..8253cf6 100644
--- a/Selector.CLI/Program.cs
+++ b/Selector.CLI/Program.cs
@@ -13,6 +13,7 @@ using Selector.Cache;
using Selector.Cache.Extensions;
using IF.Lastfm.Core.Api;
+using Selector.Model.Extensions;
namespace Selector.CLI
{
@@ -101,6 +102,7 @@ namespace Selector.CLI
Console.WriteLine("> Configuring...");
// CONFIG
var config = ConfigureOptions(context, services);
+ services.AddHttpClient();
Console.WriteLine("> Adding Services...");
// SERVICES
diff --git a/Selector.Cache/Consumer/PlayCounterCaching.cs b/Selector.Cache/Consumer/PlayCounterCaching.cs
index 3b85ee5..4303551 100644
--- a/Selector.Cache/Consumer/PlayCounterCaching.cs
+++ b/Selector.Cache/Consumer/PlayCounterCaching.cs
@@ -56,9 +56,9 @@ namespace Selector.Cache
var tasks = new Task[]
{
- Db.StringSetAsync(Key.TrackPlayCount(track.Name, track.Artists[0].Name), e.Track, expiry: CacheExpiry),
- Db.StringSetAsync(Key.AlbumPlayCount(track.Album.Name, track.Album.Artists[0].Name), e.Album, expiry: CacheExpiry),
- Db.StringSetAsync(Key.ArtistPlayCount(track.Artists[0].Name), e.Artist, expiry: CacheExpiry),
+ Db.StringSetAsync(Key.TrackPlayCount(e.Username, track.Name, track.Artists[0].Name), e.Track, expiry: CacheExpiry),
+ Db.StringSetAsync(Key.AlbumPlayCount(e.Username, track.Album.Name, track.Album.Artists[0].Name), e.Album, expiry: CacheExpiry),
+ Db.StringSetAsync(Key.ArtistPlayCount(e.Username, track.Artists[0].Name), e.Artist, expiry: CacheExpiry),
Db.StringSetAsync(Key.UserPlayCount(e.Username), e.User, expiry: CacheExpiry),
};
diff --git a/Selector.Cache/Key.cs b/Selector.Cache/Key.cs
index 9788571..63e3f58 100644
--- a/Selector.Cache/Key.cs
+++ b/Selector.Cache/Key.cs
@@ -1,40 +1,72 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Text;
namespace Selector.Cache
{
public class Key
{
- public const string CurrentlyPlayingName = "CurrentlyPlaying";
+ public const char MajorSep = ':';
+ public const char MinorSep = '.';
- public const string TrackName = "Track";
- public const string AlbumName = "Album";
- public const string ArtistName = "Artist";
- public const string UserName = "User";
+ public const string All = "*";
+ public const string CurrentlyPlayingName = "CURRENTLY_PLAYING";
- public const string AudioFeatureName = "AudioFeature";
- public const string PlayCountName = "PlayCount";
+ public const string TrackName = "TRACK";
+ public const string AlbumName = "ALBUM";
+ public const string ArtistName = "ARTIST";
+ public const string UserName = "USER";
- public const string WorkerName = "Worker";
- public const string WatcherName = "Watcher";
- public const string ReservedName = "Reserved";
+ public const string AudioFeatureName = "AUDIO_FEATURE";
+ public const string PlayCountName = "PLAY_COUNT";
+
+ public const string SpotifyName = "SPOTIFY";
+ public const string LastfmName = "LASTFM";
+
+ public const string WatcherName = "WATCHER";
///
/// Current playback for a user
///
/// User's database Id (Guid)
///
- public static string CurrentlyPlaying(string user) => Namespace(user, CurrentlyPlayingName);
- public static string AudioFeature(string trackId) => Namespace(TrackName, trackId, AudioFeatureName);
+ public static string CurrentlyPlaying(string user) => MajorNamespace(MinorNamespace(UserName, CurrentlyPlayingName), user);
+ public static readonly string AllCurrentlyPlaying = CurrentlyPlaying(All);
- public static string TrackPlayCount(string name, string artist) => Namespace(TrackName, artist, name, PlayCountName);
- public static string AlbumPlayCount(string name, string artist) => Namespace(AlbumName, artist, name, PlayCountName);
- public static string ArtistPlayCount(string name) => Namespace(ArtistName, name, PlayCountName);
- public static string UserPlayCount(string username) => Namespace(UserName, username, PlayCountName);
+ public static string AudioFeature(string trackId) => MajorNamespace(MinorNamespace(TrackName, AudioFeatureName), trackId);
+ public static readonly string AllAudioFeatures = AudioFeature(All);
- public static string WatcherReserved(int id) => Namespace(WatcherName, id.ToString(), ReservedName);
+ public static string TrackPlayCount(string username, string name, string artist) => MajorNamespace(MinorNamespace(TrackName, PlayCountName), artist, name, username);
+ public static string AlbumPlayCount(string username, string name, string artist) => MajorNamespace(MinorNamespace(AlbumName, PlayCountName), artist, name, username);
+ public static string ArtistPlayCount(string username, string name) => MajorNamespace(MinorNamespace(ArtistName, PlayCountName), name, username);
+ public static string UserPlayCount(string username) => MajorNamespace(MinorNamespace(UserName, PlayCountName), username);
- public static string Namespace(params string[] args) => string.Join(":", args);
+ public static string UserSpotify(string username) => MajorNamespace(MinorNamespace(UserName, SpotifyName), username);
+ public static readonly string AllUserSpotify = UserSpotify(All);
+ public static string UserLastfm(string username) => MajorNamespace(MinorNamespace(UserName, LastfmName), username);
+ public static readonly string AllUserLastfm = UserLastfm(All);
+
+ public static string Watcher(int id) => MajorNamespace(WatcherName, id.ToString());
+ public static readonly string AllWatcher = MajorNamespace(WatcherName, All);
+
+ public static string MajorNamespace(params string[] args) => Namespace(MajorSep, args);
+ public static string MinorNamespace(params string[] args) => Namespace(MinorSep, args);
+ public static string Namespace(char separator, params string[] args) => string.Join(separator, args);
+
+ public static string[] UnMajorNamespace(string arg) => UnNamespace(arg, MajorSep);
+ public static string[] UnMinorNamespace(string arg) => UnNamespace(arg, MinorSep);
+ public static string[] UnNamespace(string key, params char[] args) => key.Split(args);
+
+ public static string Param(string key) => UnMajorNamespace(key).Skip(1).First();
+ public static (string, string) ParamPair(string key) {
+ var split = UnMajorNamespace(key);
+ return (split[1], split[2]);
+ }
+ public static (string, string, string) ParamTriplet(string key)
+ {
+ var split = UnMajorNamespace(key);
+ return (split[1], split[2], split[3]);
+ }
}
}
diff --git a/Selector.Cache/Services/PlayCountPuller.cs b/Selector.Cache/Services/PlayCountPuller.cs
index 49c98a3..f4dfd3a 100644
--- a/Selector.Cache/Services/PlayCountPuller.cs
+++ b/Selector.Cache/Services/PlayCountPuller.cs
@@ -45,9 +45,9 @@ namespace Selector.Cache
{
if (string.IsNullOrWhiteSpace(username)) throw new ArgumentNullException("No username provided");
- var trackCache = Cache?.StringGetAsync(Key.TrackPlayCount(track, artist));
- var albumCache = Cache?.StringGetAsync(Key.AlbumPlayCount(album, albumArtist));
- var artistCache = Cache?.StringGetAsync(Key.ArtistPlayCount(artist));
+ var trackCache = Cache?.StringGetAsync(Key.TrackPlayCount(username, track, artist));
+ var albumCache = Cache?.StringGetAsync(Key.AlbumPlayCount(username, album, albumArtist));
+ var artistCache = Cache?.StringGetAsync(Key.ArtistPlayCount(username, artist));
var userCache = Cache?.StringGetAsync(Key.UserPlayCount(username));
var cacheTasks = new Task[] { trackCache, albumCache, artistCache, userCache };
diff --git a/Selector.Model/Events/UserEventBus.cs b/Selector.Model/Events/UserEventBus.cs
new file mode 100644
index 0000000..07f198a
--- /dev/null
+++ b/Selector.Model/Events/UserEventBus.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Selector.Events;
+
+namespace Selector.Model.Events
+{
+ public class UserEventBus: IEventBus
+ {
+ private readonly ILogger Logger;
+
+ public event EventHandler UserChange;
+ public event EventHandler SpotifyLinkChange;
+ public event EventHandler LastfmCredChange;
+
+ public event EventHandler<(string, CurrentlyPlayingDTO)> CurrentlyPlaying;
+
+ public UserEventBus(ILogger logger)
+ {
+ Logger = logger;
+ }
+
+ public void OnUserChange(object sender, ApplicationUser args)
+ {
+ Logger.LogTrace("Firing user event [{usernamne}]", args?.UserName);
+ UserChange?.Invoke(sender, args);
+ }
+
+ public void OnSpotifyLinkChange(object sender, ApplicationUser args)
+ {
+ Logger.LogTrace("Firing user Spotify event [{usernamne}]", args?.UserName);
+ SpotifyLinkChange?.Invoke(sender, args);
+ }
+
+ public void OnLastfmCredChange(object sender, ApplicationUser args)
+ {
+ Logger.LogTrace("Firing user Last.fm event [{usernamne}]", args?.UserName);
+ LastfmCredChange?.Invoke(sender, args);
+ }
+
+ public void OnCurrentlyPlayingChange(object sender, string userId, CurrentlyPlayingDTO args)
+ {
+ Logger.LogTrace("Firing currently playing event [{usernamne}/{userId}]", args?.Username, userId);
+ CurrentlyPlaying?.Invoke(sender, (userId, args));
+ }
+ }
+}
diff --git a/Selector.Model/Extensions/ServiceExtensions.cs b/Selector.Model/Extensions/ServiceExtensions.cs
index f26a5b1..3dba790 100644
--- a/Selector.Model/Extensions/ServiceExtensions.cs
+++ b/Selector.Model/Extensions/ServiceExtensions.cs
@@ -1,17 +1,20 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
+using Selector.Events;
using Selector.Model.Authorisation;
+using Selector.Model.Events;
namespace Selector.Model.Extensions
{
public static class ServiceExtensions
{
+ public static void AddModelEventBus(this IServiceCollection services)
+ {
+ services.AddSingleton();
+ services.AddSingleton(sp => sp.GetService());
+ }
+
public static void AddAuthorisationHandlers(this IServiceCollection services)
{
services.AddAuthorization(options =>
diff --git a/Selector.Web/Extensions/ServiceExtensions.cs b/Selector.Web/Extensions/ServiceExtensions.cs
index 3d6d308..4228a73 100644
--- a/Selector.Web/Extensions/ServiceExtensions.cs
+++ b/Selector.Web/Extensions/ServiceExtensions.cs
@@ -1,5 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Selector.Web.Service;
+using Selector.Web.Hubs;
namespace Selector.Web.Extensions
{
@@ -7,11 +8,14 @@ namespace Selector.Web.Extensions
{
public static void AddCacheHubProxy(this IServiceCollection services)
{
- services.AddSingleton();
- services.AddHostedService();
+ services.AddScoped();
+ services.AddHostedService();
- services.AddTransient();
- services.AddScoped();
+ services.AddTransient();
+ services.AddTransient();
+
+ services.AddScoped, NowPlayingHubMapping>();
+ services.AddScoped();
}
}
}
diff --git a/Selector.Web/Services/CacheHubProxyService.cs b/Selector.Web/Services/CacheEventProxyService.cs
similarity index 51%
rename from Selector.Web/Services/CacheHubProxyService.cs
rename to Selector.Web/Services/CacheEventProxyService.cs
index 9d13c86..77418ce 100644
--- a/Selector.Web/Services/CacheHubProxyService.cs
+++ b/Selector.Web/Services/CacheEventProxyService.cs
@@ -8,33 +8,38 @@ using Microsoft.Extensions.Logging;
namespace Selector.Web.Service
{
- public class CacheHubProxyService: IHostedService
+ public class CacheEventProxyService: IHostedService
{
- private readonly ILogger Logger;
- private readonly CacheHubProxy Proxy;
+ private readonly ILogger Logger;
private readonly IServiceScopeFactory ScopeFactory;
- public CacheHubProxyService(
- ILogger logger,
- CacheHubProxy proxy,
+ private readonly IEnumerable CacheEvents;
+
+ public CacheEventProxyService(
+ ILogger logger,
+ IEnumerable mappings,
IServiceScopeFactory scopeFactory
)
{
Logger = logger;
- Proxy = proxy;
ScopeFactory = scopeFactory;
+
+ CacheEvents = mappings;
}
public Task StartAsync(CancellationToken cancellationToken)
{
- Logger.LogInformation("Starting cache hub proxy");
+ Logger.LogInformation("Starting cache event proxy");
- using(var scope = ScopeFactory.CreateScope())
- {
- foreach(var mapping in scope.ServiceProvider.GetServices())
- {
- mapping.FormAll();
- }
+ foreach (var mapping in CacheEvents)
+ {
+ mapping.ConstructMapping();
+ }
+
+ using (var scope = ScopeFactory.CreateScope())
+ {
+ var hubProxy = scope.ServiceProvider.GetRequiredService();
+ hubProxy.FormMappings();
}
return Task.CompletedTask;
diff --git a/Selector.Web/Services/CacheHubProxy.cs b/Selector.Web/Services/CacheHubProxy.cs
deleted file mode 100644
index 4eccf99..0000000
--- a/Selector.Web/Services/CacheHubProxy.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-using System.Linq;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.AspNetCore.SignalR;
-
-using StackExchange.Redis;
-using Selector.Web.Hubs;
-
-namespace Selector.Web.Service
-{
- public class CacheHubProxy
- {
- private readonly ILogger Logger;
- private readonly ISubscriber Subscriber;
- private readonly IServiceProvider Services;
-
- public CacheHubProxy(ILogger logger,
- ISubscriber subscriber,
- IServiceProvider services
- )
- {
- Logger = logger;
- Subscriber = subscriber;
- Services = services;
- }
-
- public void FormMapping(ICacheHubMapping mapping) where THub: Hub where T: class
- {
- var context = Services.GetService>();
- mapping.ConstructMapping(Subscriber, context);
- }
- }
-}
\ No newline at end of file
diff --git a/Selector.Web/Services/CacheMappings/ICacheEventMapping.cs b/Selector.Web/Services/CacheMappings/ICacheEventMapping.cs
new file mode 100644
index 0000000..ceb7bf2
--- /dev/null
+++ b/Selector.Web/Services/CacheMappings/ICacheEventMapping.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Threading.Tasks;
+
+using Microsoft.AspNetCore.SignalR;
+using StackExchange.Redis;
+
+namespace Selector.Web.Service
+{
+ public interface ICacheEventMapping
+ {
+ public Task ConstructMapping();
+ }
+}
\ No newline at end of file
diff --git a/Selector.Web/Services/CacheMappings/NowPlayingCacheMapping.cs b/Selector.Web/Services/CacheMappings/NowPlayingCacheMapping.cs
new file mode 100644
index 0000000..15e1bad
--- /dev/null
+++ b/Selector.Web/Services/CacheMappings/NowPlayingCacheMapping.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Text.Json;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.SignalR;
+using Microsoft.Extensions.Logging;
+
+using StackExchange.Redis;
+
+using Selector.Web.Hubs;
+using Selector.Cache;
+using Selector.Model.Events;
+
+namespace Selector.Web.Service
+{
+ public class NowPlayingCacheMapping : ICacheEventMapping
+ {
+ private readonly ILogger Logger;
+ private readonly ISubscriber Subscriber;
+ private readonly UserEventBus UserEvent;
+
+ public NowPlayingCacheMapping(ILogger logger,
+ ISubscriber subscriber,
+ UserEventBus userEvent)
+ {
+ Logger = logger;
+ Subscriber = subscriber;
+ UserEvent = userEvent;
+ }
+
+ public async Task ConstructMapping()
+ {
+ Logger.LogDebug("Forming now playing event mapping between cache and event bus");
+
+ (await Subscriber.SubscribeAsync(Key.AllCurrentlyPlaying)).OnMessage(message => {
+
+ try{
+ var userId = Key.Param(message.Channel);
+
+ var deserialised = JsonSerializer.Deserialize(message.Message);
+ Logger.LogDebug("Received new currently playing [{username}]", deserialised.Username);
+
+ UserEvent.OnCurrentlyPlayingChange(this, userId, deserialised);
+ }
+ catch(Exception e)
+ {
+ Logger.LogError(e, $"Error parsing new currently playing [{message}]");
+ }
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/Selector.Web/Services/EventHubProxy.cs b/Selector.Web/Services/EventHubProxy.cs
new file mode 100644
index 0000000..a3e3023
--- /dev/null
+++ b/Selector.Web/Services/EventHubProxy.cs
@@ -0,0 +1,26 @@
+using Microsoft.Extensions.Logging;
+
+namespace Selector.Web.Service
+{
+ public class EventHubProxy
+ {
+ private readonly ILogger Logger;
+
+ private readonly NowPlayingHubMapping NowPlayingMapping;
+
+ public EventHubProxy(ILogger logger,
+ NowPlayingHubMapping nowPlayingMapping
+ )
+ {
+ Logger = logger;
+ NowPlayingMapping = nowPlayingMapping;
+ }
+
+ public void FormMappings()
+ {
+ Logger.LogDebug("Forming event mappings between event bus and SignalR hubs");
+
+ NowPlayingMapping.ConstructMapping();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Selector.Web/Services/EventMappings/IEventHubMapping.cs b/Selector.Web/Services/EventMappings/IEventHubMapping.cs
new file mode 100644
index 0000000..637a016
--- /dev/null
+++ b/Selector.Web/Services/EventMappings/IEventHubMapping.cs
@@ -0,0 +1,15 @@
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.SignalR;
+
+using StackExchange.Redis;
+
+namespace Selector.Web.Service
+{
+ public interface IEventHubMapping
+ where THub : Hub
+ where T : class
+ {
+ public Task ConstructMapping();
+ // public Task RemoveMapping();
+ }
+}
diff --git a/Selector.Web/Services/EventMappings/NowPlayingHubMapping.cs b/Selector.Web/Services/EventMappings/NowPlayingHubMapping.cs
new file mode 100644
index 0000000..5ffa657
--- /dev/null
+++ b/Selector.Web/Services/EventMappings/NowPlayingHubMapping.cs
@@ -0,0 +1,40 @@
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.SignalR;
+using Microsoft.Extensions.Logging;
+
+using Selector.Web.Hubs;
+using Selector.Model.Events;
+
+namespace Selector.Web.Service
+{
+ public class NowPlayingHubMapping: IEventHubMapping
+ {
+ private readonly ILogger Logger;
+ private readonly UserEventBus UserEvent;
+ private readonly IHubContext Hub;
+
+ public NowPlayingHubMapping(ILogger logger,
+ UserEventBus userEvent,
+ IHubContext hub)
+ {
+ Logger = logger;
+ UserEvent = userEvent;
+ Hub = hub;
+ }
+
+ public Task ConstructMapping()
+ {
+ Logger.LogDebug("Forming now playing event mapping between event bus and SignalR hub");
+
+ UserEvent.CurrentlyPlaying += async (o, args) =>
+ {
+ (string id, CurrentlyPlayingDTO e) = args;
+ Logger.LogDebug("Passing now playing event to SignalR hub [{userId}]", id);
+
+ await Hub.Clients.User(id).OnNewPlaying(e);
+ };
+
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git a/Selector.Web/Services/Mappings/ICacheHubMapping.cs b/Selector.Web/Services/Mappings/ICacheHubMapping.cs
deleted file mode 100644
index 7505aa6..0000000
--- a/Selector.Web/Services/Mappings/ICacheHubMapping.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Threading.Tasks;
-
-using Microsoft.AspNetCore.SignalR;
-using StackExchange.Redis;
-
-namespace Selector.Web.Service
-{
- public interface ICacheHubMapping
- where THub : Hub
- where T : class
- {
- public Task ConstructMapping(ISubscriber subscriber, IHubContext hub);
- // public Task RemoveMapping(ISubscriber subscriber, THub hub);
- }
-}
\ No newline at end of file
diff --git a/Selector.Web/Services/Mappings/NowPlayingMapping.cs b/Selector.Web/Services/Mappings/NowPlayingMapping.cs
deleted file mode 100644
index 9eb8830..0000000
--- a/Selector.Web/Services/Mappings/NowPlayingMapping.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System;
-using System.Text.Json;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.SignalR;
-using Microsoft.Extensions.Logging;
-
-using StackExchange.Redis;
-
-using Selector.Web.Hubs;
-using Selector.Cache;
-
-namespace Selector.Web.Service
-{
- public class NowPlayingMapping : ICacheHubMapping
- {
- private readonly ILogger Logger;
- private readonly string UserId;
- private readonly string Username;
-
- public NowPlayingMapping(ILogger logger, string userId, string username)
- {
- Logger = logger;
- UserId = userId;
- Username = username;
- }
-
- public async Task ConstructMapping(ISubscriber subscriber, IHubContext hub)
- {
- var key = Key.CurrentlyPlaying(UserId);
- (await subscriber.SubscribeAsync(key)).OnMessage(async message => {
-
- try{
- var trimmedMessage = message.ToString().Substring(key.Length + 1);
- var deserialised = JsonSerializer.Deserialize(trimmedMessage);
- Logger.LogDebug($"Received new currently playing [{deserialised.Username}] [{deserialised.Username}]");
- await hub.Clients.User(UserId).OnNewPlaying(deserialised);
- }
- catch(Exception e)
- {
- Logger.LogError(e, $"Error parsing new currently playing [{message}]");
- }
- });
- }
- }
-}
\ No newline at end of file
diff --git a/Selector.Web/Services/Mappings/NowPlayingMappingFactory.cs b/Selector.Web/Services/Mappings/NowPlayingMappingFactory.cs
deleted file mode 100644
index 305d504..0000000
--- a/Selector.Web/Services/Mappings/NowPlayingMappingFactory.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-using Microsoft.AspNetCore.SignalR;
-using Microsoft.Extensions.Logging;
-
-using Selector.Web.Hubs;
-
-namespace Selector.Web.Service
-{
- public interface IUserMappingFactory
- where TMap : ICacheHubMapping
- where THub : Hub
- where T : class
- {
- public TMap Get(string userId, string username);
- }
-
- public interface INowPlayingMappingFactory: IUserMappingFactory
- { }
-
- public class NowPlayingMappingFactory : INowPlayingMappingFactory {
-
- private readonly ILoggerFactory LoggerFactory;
-
- public NowPlayingMappingFactory(ILoggerFactory loggerFactory)
- {
- LoggerFactory = loggerFactory;
- }
-
- public NowPlayingMapping Get(string userId, string username)
- {
- return new NowPlayingMapping(
- LoggerFactory?.CreateLogger(),
- userId,
- username
- );
- }
- }
-}
diff --git a/Selector.Web/Services/Mappings/UserMapping.cs b/Selector.Web/Services/Mappings/UserMapping.cs
deleted file mode 100644
index 18d49e7..0000000
--- a/Selector.Web/Services/Mappings/UserMapping.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-using System.Linq;
-
-using Selector.Model;
-
-namespace Selector.Web.Service
-{
- public interface IUserMapping {
- public void FormAll();
- }
-
- public class NowPlayingUserMapping: IUserMapping
- {
- private readonly ApplicationDbContext Db;
- private readonly CacheHubProxy Proxy;
- private readonly INowPlayingMappingFactory NowPlayingMappingFactory;
-
- public NowPlayingUserMapping(
- ApplicationDbContext db,
- CacheHubProxy proxy,
- INowPlayingMappingFactory nowPlayingMappingFactory
- )
- {
- Db = db;
- Proxy = proxy;
- NowPlayingMappingFactory = nowPlayingMappingFactory;
- }
-
- public void FormAll()
- {
- foreach(var user in Db.Users)
- {
- Proxy.FormMapping(NowPlayingMappingFactory.Get(user.Id, user.UserName));
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Selector.Web/Startup.cs b/Selector.Web/Startup.cs
index c129f86..4e57ff1 100644
--- a/Selector.Web/Startup.cs
+++ b/Selector.Web/Startup.cs
@@ -48,6 +48,7 @@ namespace Selector.Web
services.AddRazorPages().AddRazorRuntimeCompilation();
services.AddControllers();
services.AddSignalR(o => o.EnableDetailedErrors = true);
+ services.AddHttpClient();
services.AddDbContext(options =>
options.UseNpgsql(Configuration.GetConnectionString("Default"))
@@ -92,6 +93,7 @@ namespace Selector.Web
});
services.AddAuthorisationHandlers();
+ services.AddModelEventBus();
if (config.RedisOptions.Enabled)
services.AddRedisServices(config.RedisOptions.ConnectionString);
diff --git a/Selector/Events/IEventBus.cs b/Selector/Events/IEventBus.cs
new file mode 100644
index 0000000..cd8a75d
--- /dev/null
+++ b/Selector/Events/IEventBus.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Selector.Events
+{
+ public interface IEventBus
+ {
+
+ }
+}