Reputation: 41
I'm completely new to both autofac and singalR libraries, so please be easy on me! I've got the following code in bootstrapper which works on its own without signalR.
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();
builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerHttpRequest();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest();
builder.RegisterAssemblyTypes(typeof(adminRepository).Assembly).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces().InstancePerHttpRequest();
builder.RegisterAssemblyTypes(typeof(adminService).Assembly).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces().InstancePerHttpRequest();
builder.RegisterFilterProvider();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new Autofac.Integration.Mvc.AutofacDependencyResolver(container));
Above code works just fine but after registering my Hub with this below code, it just doesn't work.
builder.RegisterType<Chat>().InstancePerLifetimeScope();
builder.RegisterFilterProvider();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new Autofac.Integration.Mvc.AutofacDependencyResolver(container));
SignalR.IDependencyResolver resolver = new SignalR.Autofac.AutofacDependencyResolver(container);
GlobalHost.DependencyResolver = resolver;
RouteTable.Routes.MapHubs(resolver);
I'm using SignalR dependency resolver binding to Autofac from this (https://github.com/pszmyd/SignalR.Autofac).
I've got a simple hub like this,
public class Chat : Hub
{
private readonly IadminService adminService;
public Chat(IadminService adminService)
{
this.adminService = adminService;
}
public void Send(string message)
{
Clients.addMessage(message);
}
}
This is the error I've got when I tried to use DI to the hub.
"No scope with a Tag matching 'httpRequest' is visible from the scope in which the instance was requested."
No matter what I do, I can't seem to get it working and I'd be grateful if someone could please tell me what's wrong with the code above.
Many Thanks Leo
Upvotes: 4
Views: 2769
Reputation: 6258
For an ASP.NET application hosted in IIS add this to Application_Start:
var container = AutofacConfig.BuildContainer();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
var signalRDependencyResolver = new SignalRAutofacDependencyResolver(container);
// old SignalR 1.0 way - routes.MapHubs(signalRDependencyResolver);
RouteTable.Routes.MapHubs(new HubConfiguration { Resolver = signalRDependencyResolver });
You may find the SignalRAutofacDependencyResolver here.
Example hub injecting an ISecurity service:
public class ExampleHub : Hub
{
private static int _count = 0;
private readonly ISecurity _security;
public ExampleHub(ISecurity security)
{
_security = security;
}
public void GetCount()
{
_count++;
Clients.All.SetCount(_count);
}
}
This also works with SignalR self host release. Just use a startup class like this:
// These are static variables in Program.cs - Probably a better way to do this
_container = AutofacConfig.BuildContainer();
_webServer = WebApp.Start<WebServerStartup>("http://localhost:8080");
public class WebServerStartup
{
private readonly SignalRAutofacDependencyResolver _signalRDependencyResolver;
public WebServerStartup()
{
_signalRDependencyResolver = new SignalRAutofacDependencyResolver(_container);
}
public void Configuration(IAppBuilder app)
{
app.MapSignalR(new HubConfiguration { Resolver = _signalRDependencyResolver });
}
}
Upvotes: 3
Reputation: 20674
After setting the DependencyResolver do you still need to pass it to MapHubs, that is try this instead:
GlobalHost.DependencyResolver = resolver;
RouteTable.Routes.MapHubs();
I know SignalR but never used Autofac but it may be worth looking at these answers for details on possible Autofac issue:
How to resolve Autofac InstancePerHttpRequest
Upvotes: 1