SignalR + Autofac + OWIN: Why doesn't GlobalHost.ConnectionManager.GetHubContext work?
If you use a custom dependency resolver with SignalR, you can no longer use GlobalHost
unless you modify it:
GlobalHost.DependencyResolver = new AutofacDependencyResolver(container);IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>();// A custom HubConfiguration is now unnecessary, since MapSignalR will// use the resolver from GlobalHost by default.app.MapSignalR();
If you don't want to modify GlobalHost, you will have to manually resolve your IConnectionManager:
IDependencyResolver resolver = new AutofacDependencyResolver(container);IHubContext hubContext = resolver.Resolve<IConnectionManager>().GetHubContext<MyHub>();app.MapSignalR(new HubConfiguration{ Resolver = resolver});
For a complete answer, with SignalR, Autofac, and OWIN, I did the following:
// register IPersistantConnectionContext for access to SignalR connection// and IDependencyResolver to enable inection of the container into its// construction for the config object.var builder = new ContainerBuilder();builder.RegisterType<Autofac.Integration.SignalR.AutofacDependencyResolver>() .As<IDependencyResolver>() .SingleInstance();builder.Register((context, p) => context.Resolve<IDependencyResolver>() .Resolve<Microsoft.AspNet.SignalR.Infrastructure.IConnectionManager>() .GetConnectionContext<SignalRConnection>());// ... other registrationsvar container = builder.Build();var signalrConfiguration = new ConnectionConfiguration{ Resolver = container.Resolve<IDependencyResolver>(),};app.UseAutofacMiddleware(container);app.MapSignalR<SignalRConnection>("/signalr", signalrConfiguration);// ... other middleware
In my controllers, I included a parameter of the type IPersistentConnectionContext
and the correct instance is injected.
I was using a PersistentConnection, but it should be similar for Hubs.
To expand on Nathan's answer, I am using something similar with the key line being
builder.RegisterHubs(Assembly.GetExecutingAssembly()).SingleInstance();
in Startup.cs.
The line "SingleInstance()" ensures that only a single "instance" of the hub is used throughout the application.
Then I just use straightforward dependency injection into the constructor of the controller to get a pointer to the hub.