Autofac DependencyResolutionException for ILifetimeScope for Hub in asp.net mvc, signalr, MS owin

What should be the Autofac 3.5 configuration for Asp.net Mvc 5.2, SignalR 2.1, MS Owin (Katana) 3.0? Is there a less complicated way to register Autofac auto-interceptors (there are currently two)? Or why is ILifetimeScope

n't it showing up for my hub?

An exception:

Autofac.Core.DependencyResolutionException: Fixed exception when calling constructor 'Void.ctor (Autofac.ILifetimeScope)' on type "OperatorHub". --->

No scope tagged with "AutofacWebRequest" is visible from the scope where the instance was requested. This usually indicates that a component registered as an HTTP request is being requested by a SingleInstance () component (or a similar scenario.) Web integration always requests dependencies on DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself. (See Inner Exception for details). --->

Autofac.Core.DependencyResolutionException: Without the scope tagged, the "AutofacWebRequest" match is visible from the scope in which the instance is requested. This usually indicates that a component registered as an HTTP request is requested by SingleInstance () (or a similar scenario.) On the web, the integration always requests dependencies on 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) });
}

      

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

Breaking Component Registration (EF Context:

        builder.RegisterType<MyDbContext>().AsSelf().As<DbContext>().InstancePerRequest("OwinLifetimeScope");

      

In short, the error is MyDbContext

not in the "root" scope, which is passed to the constructor OperatorHub

.

UPDATE 2

The @TravisIllig solution is to register the MyDbContext service with .InstancePerLifetimeScope()

and create it in the hub. A different time-to-live area will be created for the HTTP request in the asp mvc. Create help in Sharing Dependencies in All Applications without prompts .

In addition, the hub should not delete the specified area as it is the root area, which results ObjectDisposedException

in a second run.

+3


source to share


1 answer


There are many questions about handling this exact exception on the Autofac doc site . The problem has to do with what you are using InstancePerRequest

in conjunction with SignalR, which is also in the documentation :

Due to the internal functionality of SignalR, SignalR has no support for dependencies throughout every request.



You seem to have looked at the Autofac SignalR docs as I see you have introduced a lifetime to help you manage the lifetime of an instance, but that doesn't give you on-demand lifetime coverage, it just gives you the lifetime in the hub. I might suggest revisiting this document for an update.

The FAQs I mentioned along with the SignalR integration docs should point you to the right solution for your application. A lot of people just switch their registrations from InstancePerRequest

to InstancePerLifetimeScope

, but I highly recommend that you read the FAQ and check your options before simply moving on to such a solution. It might be the right choice, but it might not - it depends on how your application works internally.

+7


source







All Articles