Reputation: 944
I have a SignalR 2 project that also uses WebApi and I'm trying to integrate AutoFac into this.
Initially, my Startup class looked like this:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.MapSignalR();
var httpConfig = new HttpConfiguration();
httpConfig.MapHttpAttributeRoutes();
app.UseWebApi(httpConfig);
}
}
which doesn't use autofac and everything works fine. Now, I'm trying to add in AutoFac so I changed my Startup class to look like this:
public void Configuration(IAppBuilder app)
{
var builder = new ContainerBuilder();
var httpConfig = new HttpConfiguration();
var hubConfig = new HubConfiguration();
// Register your Web API controllers.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterHubs(Assembly.GetExecutingAssembly());
var container = builder.Build();
httpConfig.DependencyResolver = new AutofacWebApiDependencyResolver(container);
hubConfig.Resolver = new AutofacDependencyResolver(container);
app.UseAutofacMiddleware(container);
app.MapSignalR("/signalr", hubConfig);
app.UseWebApi(httpConfig);
}
Now what happens is I'm not able to make calls to my controller, as I get a 404 each time I make a call, which worked before. What am I missing? On the autofac quickstart guide for web api there is a call to app.UseAutofacWebApi(config), however, that method doesn't exist, so, not sure if that's the issue or what.
Upvotes: 1
Views: 938
Reputation: 613
I had the same issue. For me, I had to add the hubs individually and use Nuget Packages Autofac.SignalR version 3.0.2 and SignalR.Extras.Autofac v1.2.0. There are a couple of Autofac SignalR packages, make sure it's those two only.
Though I changed a few other things as well. Here's how I did it. var builder = new ContainerBuilder();
// REGISTER CONTROLLERS SO DEPENDENCIES ARE CONSTRUCTOR INJECTED
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// Register the SignalR hubs.
builder.RegisterType<UpdateHub>().ExternallyOwned();
builder.RegisterType<NotificationHub>().ExternallyOwned();
// BUILD THE CONTAINER
var container = builder.Build();
// Configure SignalR with an instance of the Autofac dependency resolver.
GlobalHost.DependencyResolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(container);
DependencyResolver.SetResolver(new Autofac.Integration.Mvc.AutofacDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver((IContainer)container);
// REGISTER WITH OWIN
app.UseAutofacMiddleware(container);
app.UseAutofacMvc();
app.MapSignalR();
ConfigureAuth(app);
Another mistake I did was thinking the hub itself can be injected into a controller. You cannot do that, so if you have a need for that you must do through the hub context, I need to find a way to inject the hub context. That's on my todo.
var updateHubContext = GlobalHost.ConnectionManager.GetHubContext<UpdateHub>();
updateHubContext.Clients.All.update();
And if you need a lifetime scope, you must resolve your dependencies into your hub using the interface ILifetimeScope. You need to inject the Lifetime Scope and then resolve them from that.
private readonly ILifetimeScope _hubLifetimeScope;
private readonly IEntityService<Update> _updateService;
public UpdateHub(ILifetimeScope lifetimeScope)
{
//the AutofacWebRequest is important. It will not work without it
_hubLifetimeScope = lifetimeScope.BeginLifetimeScope("AutofacWebRequest");
_updateService = _hubLifetimeScope.Resolve<IEntityService<Update>>();
}
Hopefully this helps. The javascript is the same from the tutorials on the site. Nothing changes there.
Upvotes: 1