Created
August 11, 2016 10:41
-
-
Save pmbanugo/99933fc8ec58e96e8e6a7f972ed9e5be to your computer and use it in GitHub Desktop.
Using SimpleInjector with SignalR: Injecting Services into SignalR Hubs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ChatHub : Hub | |
{ | |
private readonly Container _container; | |
public ChatHub(Container container) | |
{ | |
_container = container; | |
} | |
public override Task OnConnected() | |
{ | |
var userId = Context.User.GetUserID(); | |
_container.GetInstance<IChatService>().OnConnected(userId, Context.ConnectionId, Clients); | |
return base.OnConnected(); | |
} | |
public override Task OnDisconnected() | |
{ | |
using (_container.BeginExecutionContextScope()) | |
{ | |
var userId = Context.User.GetUserID(); | |
_container.GetInstance<IChatService>().OnDisconnected(userId, Context.ConnectionId, Clients); | |
return base.OnDisconnected(); | |
} | |
} | |
public void Broadcast(string message) | |
{ | |
_container.GetInstance<IChatService>().Broadcast(message, Context.User.Identity.Name, Clients); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ChatService : IChatService | |
{ | |
private readonly IUnitOfWork _unitOfWork; | |
public ChatService(IUnitOfWork unitOfWork) | |
{ | |
_unitOfWork = unitOfWork; | |
} | |
public void OnConnected(Guid userId, string connectionId, HubConnectionContext clients) | |
{ | |
var existingConnection = _unitOfWork.UserConnectionRepository.Get(x => x.UserId == userId); | |
if (!existingConnection.Any()) | |
{ | |
//TODO: get username from db | |
clients.Others.userOnline(userId, DateTime.UtcNow.TimeOfDay);//notify other connected users | |
} | |
SaveUserConnection(userId, connectionId); | |
var onlineUsers = _unitOfWork.UserConnectionRepository.GetOnlineUsers().Select(userConnection => new | |
{ | |
name = userConnection.Name, | |
id = userConnection.UserId | |
}); | |
clients.Caller.setOnlineUsers(onlineUsers); | |
} | |
private void SaveUserConnection(Guid userId, string userConnectionId) | |
{ | |
try | |
{ | |
var userConnection = new UserConnection() { ConnectionId = userConnectionId, UserId = userId }; | |
_unitOfWork.UserConnectionRepository.Insert(userConnection); | |
_unitOfWork.SaveChanges(); | |
} | |
catch (Exception) | |
{ | |
//TODO: Log exception | |
} | |
} | |
public void OnDisconnected(Guid userId, string connectionId, HubConnectionContext clients) | |
{ | |
try | |
{ | |
_unitOfWork.UserConnectionRepository.Delete(userId, connectionId); | |
_unitOfWork.SaveChanges(); | |
} | |
catch (Exception) | |
{ | |
//TODO: log exception | |
} | |
var existingConnection = _unitOfWork.UserConnectionRepository.Get(x => x.UserId == userId); | |
if (!existingConnection.Any()) | |
{ | |
//TODO: get username from db | |
clients.All.userOffline(userId); //notify other connected users | |
} | |
} | |
public void Broadcast(string message, string username, HubConnectionContext clients) | |
{ | |
var time = DateTime.Now.ToString("D") + " at " + DateTime.Now.ToString("h:mm:ss tt"); | |
string picture; | |
clients.All.newMessage(message, username, time); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface IChatService | |
{ | |
void OnConnected(Guid userId, string connectionId, HubConnectionContext clients); | |
void OnDisconnected(Guid userId, string connectionId, HubConnectionContext clients); | |
void Broadcast(string message, string username, HubConnectionContext clients); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
..... | |
// Create the container as usual. | |
var container = new Container(); | |
//hybrid lifestyle | |
var hybrid = Lifestyle.CreateHybrid( | |
() => container.GetCurrentExecutionContextScope() != null, | |
new ExecutionContextScopeLifestyle(), | |
new SimpleInjector.Integration.Web.WebRequestLifestyle()); | |
......... | |
container.Register(() => new DataAccess.EF.DataContext(), hybrid); | |
container.Register<IUnitOfWork, UnitOfWork>(hybrid); | |
container.Register<IChatService, ChatService>(hybrid); | |
....... | |
var activator = new SimpleInjectorHubActivator(container); | |
GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => activator); | |
........... | |
Tip: instead of reusing hybrid variable throught the composition root, you can also set it as the default scoped lifestyle | |
like this (it all depends on what you want): | |
container.Options.DefaultScopedLifestyle = hybrid; | |
container.Register<IChatService, ChatService>(Lifestyle.Scoped); | |
..... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SimpleInjectorHubActivator : IHubActivator | |
{ | |
private readonly Container _container; | |
public SimpleInjectorHubActivator(Container container) | |
{ | |
_container = container; | |
} | |
public IHub Create(HubDescriptor descriptor) | |
{ | |
return (IHub)_container.GetInstance(descriptor.HubType); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment