This post demonstrates how to use Unity as an IoC for SignalR. To inject into SignalR, the Microsoft.AspNet.SignalR.Hubs.IHubActivator class should be used.
Code: https://github.com/damienbod/SignalRHostWithUnity
Step 1:
Use NuGet to add Unity and SignalR
Step 2:
Create an UnityHubActivator class.
This class implements the IHubActivator interface. The Unity container is used in the public IHub Create(HubDescriptor descriptor) method.
using System; using Microsoft.AspNet.SignalR.Hubs; using Microsoft.Practices.Unity; namespace SignalRHostWithUnity.Unity { public class UnityHubActivator : IHubActivator { private readonly IUnityContainer _container; public UnityHubActivator(IUnityContainer container) { _container = container; } public IHub Create(HubDescriptor descriptor) { if (descriptor == null) { throw new ArgumentNullException("descriptor"); } if (descriptor.HubType == null) { return null; } object hub = _container.Resolve(descriptor.HubType) ?? Activator.CreateInstance(descriptor.HubType); return hub as IHub; } } }
Step 3:
Create an UnityConfiguration class and register your Hub class. Important is the IHubActivator registry:
using System; using Microsoft.AspNet.SignalR.Hubs; using Microsoft.Practices.Unity; using SignalRHostWithUnity.DataAccess; namespace SignalRHostWithUnity.Unity { public class UnityConfiguration { #region Unity Container private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => { var container = new UnityContainer(); RegisterTypes(container); return container; }); public static IUnityContainer GetConfiguredContainer() { return container.Value; } #endregion public static void RegisterTypes(IUnityContainer container) { container.RegisterType<MyHub, MyHub>(new ContainerControlledLifetimeManager()); container.RegisterType<IHubActivator, UnityHubActivator>(new ContainerControlledLifetimeManager()); container.RegisterType<IRepositoryUnityTestClass, RepositoryUnityTestClass>(); } } }
Now the Hub class can use constructor injection.
public class MyHub : Hub { private readonly IRepositoryUnityTestClass _repositoryUnityTestClass; public MyHub(IRepositoryUnityTestClass repositoryUnityTestClass) { _repositoryUnityTestClass = repositoryUnityTestClass; } public void AddMessage(string name, string message) { Console.WriteLine("Hub AddMessage {0} {1}\n", name, _repositoryUnityTestClass.SayHello() + message); Clients.All.addMessage(name, _repositoryUnityTestClass.SayHello() + message); }
Step 4:
Register your UnityHubActivator class to the GlobalHost.DependencyResolver
using System; using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; using Microsoft.Owin; using Microsoft.Owin.Hosting; using SignalRHostWithUnity.Dto; using SignalRHostWithUnity.Unity; namespace SignalRHostWithUnity { class Program { private static IHubContext _hubContext; static void Main(string[] args) { GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => new UnityHubActivator(UnityConfiguration.GetConfiguredContainer())); string url = "http://localhost:8089"; using (WebApp.Start(url)) { _hubContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>(); Console.WriteLine("Server running on {0}", url); while (true) { string key = Console.ReadLine(); if (key.ToUpper() == "W") { _hubContext.Clients.All.addMessage("server", "ServerMessage"); Console.WriteLine("Server Sending addMessage\n"); } if (key.ToUpper() == "E") { _hubContext.Clients.All.heartbeat(); Console.WriteLine("Server Sending heartbeat\n"); } if (key.ToUpper() == "R") { var helloModel = new HelloModel {Age = 37, Molly = "pushed direct from Server "}; _hubContext.Clients.All.sendHelloObject(helloModel); Console.WriteLine("Server Sending sendHelloObject\n"); } if (key.ToUpper() == "C") { break; } } Console.ReadLine(); } } } }
The Hub class is now resolved using unity and standard constructor injection can be used.
Links
Thanks for writing this post! I needed exactly this and it works great!
This article was a great help to get this setup, thank you.
Thanks you so much, many tuto on internet didn’t work but yours is perfect !
cheers thanks, greetings Damien
Thank you very much. I needed the exact thing to run my SignalR Hub
Is it using unity3d engine?
Unity IoC 🙂
[…] Server端:USING SIGNALR WITH UNITY […]
[…] Using SignalR with Unity | Software Engineering […]