当前位置 : 主页 > 网络编程 > ASP >

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

来源:互联网 收集:自由互联 发布时间:2021-06-24
什么应该是 Asp.net Mvc 5.2,SignalR 2.1,MS Owin(Katana)3.0的Autofac 3.5配置?注册Autofac解析器的方法是否不那么复杂(现在有两个)?或者为什么ILifetimeScope对我的集线器不可见? 例外: Autofac.Core.
什么应该是 Asp.net Mvc 5.2,SignalR 2.1,MS Owin(Katana)3.0的Autofac 3.5配置?注册Autofac解析器的方法是否不那么复杂(现在有两个)?或者为什么ILifetimeScope对我的集线器不可见?

例外:

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.

在我的OwinStartup中(见autofac + mvc owin和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) });
}

枢纽:

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

破坏组件注册(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的根作用域.

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

Due to SignalR internals, there is no support in SignalR for per-request lifetime dependencies.

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

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

网友评论