ILifetimeScope的autofac DependencyResolutionException用于asp.net中的集线器mvc,signalr,MS owin

时间:2014-12-22 13:48:42

标签: asp.net asp.net-mvc signalr autofac owin

Asp.net Mvc 5.2,SignalR 2.1,MS Owin(Katana)3.0的Autofac 3.5配置应该是什么?注册Autofac解析器的方法是否不那么复杂(现在有两个)?或者为什么ILifetimeScope对我的中心不可见?

例外:

  

Autofac.Core.DependencyResolutionException:抛出异常   在调用构造函数'Void .ctor(Autofac.ILifetimeScope)'时   输入'OperatorHub'。 --->

     

没有标记匹配的范围   从实例的范围可以看到“AutofacWebRequest”   被要求了。这通常表示注册为的组件   SingleInstance()组件正在请求每HTTP请求   (或类似场景。)在Web集成下始终请求   来自DependencyResolver.Current或的依赖项   ILifetimeScopeProvider.RequestLifetime,永远不会从容器中   本身。 (详见内部异常。)--->

     

Autofac.Core.DependencyResolutionException:没有带标记的范围   匹配'AutofacWebRequest'是从其中的范围可见的   请求实例。这通常表示一个组件   a请求注册为每个HTTP请求   SingleInstance()组件(或类似场景。)在Web下   集成始终请求来自的依赖项   DependencyResolver.Current或ILifetimeScopeProvider.RequestLifetime,   从来没有从容器本身。

在我的OwinStartup中(请参阅autofac + mvc owinautofac + 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) });
}

集线器:

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>();

    }
}

更新

破坏组件注册(EF上下文:

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

简而言之,错误是MyDbContext不在'root'生命周期范围内,并传递给OperatorHub构造函数。

更新2

在@TravisIllig的帮助下,解决方案是使用.InstancePerLifetimeScope()注册MyDbContext服务,并在集线器中创建一个。将在asp mvc中为http请求创建另一个生命周期范围。在Sharing Dependencies Across Apps Without Requests处创建帮助。

中心也不应该处理给定的范围,因为它是在第二次运行时导致ObjectDisposedException的根目录。

1 个答案:

答案 0 :(得分:7)

There is an FAQ on handling this exact exception on the Autofac doc site.问题源于您将InstancePerRequest与SignalR结合使用,also per the documentation

  

由于SignalR内部,SignalR中不支持每个请求的生命周期依赖性。

您确实看了the Autofac SignalR docs,因为我看到您注入了一个生命周期范围来帮助您管理实例生命周期,但这并没有为您提供每个请求的生命周期范围,它只是为您提供集线器生命周期范围。我可能会建议重新访问该文档以进行复习。

The FAQ I mentioned与SignalR集成文档一起,应该为您的应用指出正确的解决方案。很多人只是将注册时间从InstancePerRequest切换到InstancePerLifetimeScope,但我强烈建议您阅读常见问题解答,然后在跳转到该决定之前查看您的选项。它可能是正确的选择,但可能不是 - 这取决于您的应用程序在内部的工作方式。