What should be the Autofac 3.5 configuration for Asp.net Mvc 5.2, SignalR 2.1, MS Owin (Katana) 3.0? Is there less complex way to register Autofac resolvers (there is two of them now)? Or why ILifetimeScope
is not visible for my hub?
The exception:
Autofac.Core.DependencyResolutionException: An exception was thrown while invoking the constructor 'Void .ctor(Autofac.ILifetimeScope)' on type 'OperatorHub'. --->
No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself. (See inner exception for details.) --->
Autofac.Core.DependencyResolutionException: No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
In my OwinStartup (see autofac + mvc owin and autofac + signalr in owin):
public void Configuration(IAppBuilder app)
{
var builder = new ContainerBuilder();
// ... registration. There is .InstancePerRequest() and .SingleInstance()
Autofac.Integration.Mvc.RegistrationExtensions.RegisterControllers(builder,typeof(MvcApplication).Assembly);
Autofac.Integration.SignalR.RegistrationExtensions.RegisterHubs(builder, Assembly.GetExecutingAssembly());
var container = builder.Build();
// 1st resolver
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
app.UseAutofacMiddleware(container);
app.UseAutofacMvc();
// yet the 2nd resolver!
app.MapSignalR(new HubConfiguration { Resolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(container) });
}
The hub:
public class OperatorHub : Hub
{
public OperatorHub(ILifetimeScope hubLifetimeScope)
{
hubLifetimeScope.BeginLifetimeScope();
// ...
// HERE IT FALLS. The IMyService relates to MyDbContext (see below)
var myservice = hubLifetimeScope.Resolve<IMyService>();
}
}
UPDATE
The breaking component registration (EF Context:
builder.RegisterType<MyDbContext>().AsSelf().As<DbContext>().InstancePerRequest("OwinLifetimeScope");
In short the bug is the MyDbContext
is not in the 'root' lifetime scope which is passed to OperatorHub
constructor.
UPDATE 2
The solution with the help of @TravisIllig is to register the MyDbContext service using .InstancePerLifetimeScope()
and to create the one in the hub. Another lifetime scope would be created for http request in asp mvc. Create help at Sharing Dependencies Across Apps Without Requests.
Also the hub should not dispose the given scope as it is the root one which results in ObjectDisposedException
on the second run.