SignalR + Autofac + OWIN: Why doesn't GlobalHost.ConnectionManager.GetHubContext work? SignalR + Autofac + OWIN: Why doesn't GlobalHost.ConnectionManager.GetHubContext work? asp.net asp.net

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.