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 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>();
}
}
更新
破坏组件注册(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
的根目录。
答案 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
,但我强烈建议您阅读常见问题解答,然后在跳转到该决定之前查看您的选项。它可能是正确的选择,但可能不是 - 这取决于您的应用程序在内部的工作方式。