I am trying to configure an MVC 5 application to use SignalR 2.2.x and inject a service into my NotificationsHub
.
We are using Autofac for MVC but I am not sure on how to correctly configure this.
Autofac documentation exists for NuGet Autofac.Integration.SignalR (3.0.2)
and Autofac.Integration.Mvc (3.3.4)
.
What I am doing so far is register the hubs via:
ContainerBuilder builder = new ContainerBuilder();
// Register MVC controllers.
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<ServiceForSignalRHub>().AsImplementedInterfaces();
builder.RegisterType<...>().AsImplementedInterfaces();
builder.RegisterHubs(Assembly.GetExecutingAssembly());
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
However the call to .SetResolver(...)
is ambigious as it exists in both MVC and SignalR integration packages. Now what? I am unable to confirm if the contructor injection of my service works for the Hub I am using.
EDIT
I can configure MVC5 with Autofac just fine. Where I get lost is how to do the same with SignalR, using the Autofac Signal integration NuGet. Please see below.
This is my startup class:
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var defaultFactory = LogManager.Use<DefaultFactory>();
defaultFactory.Directory("@D:\\NServiceBus\\ );
defaultFactory.Level(LogLevel.Debug);
var container = ConfigureAutofac(app);
ConfigureServiceBus(container, app);
app.UseAutofacMiddleware(container); // REGISTER WITH OWIN
app.UseAutofacMvc();
ConfigureAuth(app);
GlobalConfiguration.Configuration.UseSqlServerStorage("hangfire");
ConfigureSignalR(app);
}
}
This is the part where I configure SignalR:
public partial class Startup
{
public void ConfigureSignalR(IAppBuilder app)
{
var builder = new ContainerBuilder();
builder.RegisterHubs(Assembly.GetExecutingAssembly()).PropertiesAutowired();
builder.RegisterType<MaintenanceService>().As<IMaintenanceService>().PropertiesAutowired();
var container = builder.Build();
//var container = new AutofacContainer().Container;
var resolver = new AutofacDependencyResolver(container);
// Any connection or hub wire up and configuration should go here
app.MapSignalR(new HubConfiguration
{
Resolver = resolver,
EnableJSONP = true,
EnableDetailedErrors = true,
EnableJavaScriptProxies = true
});
builder.RegisterInstance(resolver.Resolve<IConnectionManager>());
}
}
How can this be correctly done?
You should tell SignalR explicitly to use the
AutofacDependencyResolver
when you are mapping it. I assume that you know that in yourStartup
class you have to callapp.MapSignalR();
When you are mapping it, you should tell it to use the custom dependency resolver (the
AutofacDependencyResolver
).Here's how I do it:
This way, you are telling SignalR directly which dependency resolver to use.
I have a GitHub repo for SignalR Dependency Injection, but it's not configured to use MVC. Still, I think it will give you a hint in how to create your configuration.
Note: If you are using the OWIN Middleware, be sure not to use the
GlobalHost
static property AT ALL since it will have massive inconsistencies.Again, check the repo I gave you to see how to do this.
Hope this helps:) Best of luck!
Install nuget package Autofac.SignalR, for example:
Register your hubs
Set signalr service locator
For more information:
https://autofaccn.readthedocs.io/en/latest/integration/signalr.html
https://docs.microsoft.com/en-us/aspnet/signalr/overview/advanced/dependency-injection
I ended up with this (pay attention to comments):
_
_
Thanks to @Nathan and his answer (originally found here) and logical thinking to figure out to register ConnectionManager as IConnectionManager