我将 Autofac IoC 容器与提供 InstancePerHttpRequest 生命周期范围的 MVC4 附加组件一起使用。但是在我的项目中,我有 web、web-api 和后台工作线程。在下面的示例中,我假设 InstancePerHttpRequest 范围在不是源自 Web 请求时意义不大。
builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>()
.InstancePerHttpRequest()
我想知道是否可以像下面的例子那样让容器选择最合适的生命周期范围?
builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>()
.InstancePerHttpRequest()
.InstancePerApiRequest()
.InstancePerDependency();
在这种情况下,我打算发生的是,如果请求源自 Web 请求,那么它将选择 InstancePerHttpRequest 范围,如果它源自 webApi 请求,它将选择 InstancePerApiRequest 范围,如果它被应用程序 worker 使用线程它将使用 InstancePerDependency 范围?
如果这个或类似的东西是可能的,有什么想法吗?
谢谢
最佳答案
这个问题与这些有一些相当大的重叠:
- Managing AutoFac lifetime scopes per session and request in asp.net mvc 3
- Instance per matching lifetime scope, with default?
- Autofac - Lifetime and modules
- Autofac Lifetimes and the Default Provider within a Matching Lifetime Scope
您需要查看这些以获取一些想法。
简短的回答是:开箱即用不支持这种事情。您需要做几件事中的一件。
选项:您可以为后台线程使用不同的容器。这不允许您共享应用程序级单例,但对于您的应用程序来说可能没问题。
选项:您可以在容器之外创建两个生命周期范围,并在调用 BeginLifetimeScope
时进行不同的注册。这将允许您共享应用程序级单例并且在不同的上下文中对于相同的组件具有不同的生命周期范围。不过,管理注册有点困难,您需要两个不同的服务定位器(例如,DependencyResolver
),因为每个逻辑上下文都需要从其自己的范围内解析。
var builder = new ContainerBuilder();
builder.RegisterType<AppLevelSingleton>().SingleInstance();
var container = builder.Build();
// Create a nested lifetime scope for your background threads
// that registers things as InstancePerDependency, etc. Pass
// that scope to whatever handles dependency resolution on the thread.
var backgroundScope = container.BeginLifetimeScope(
b => b.RegisterType<DatabaseFactory>()
.As<IDatabaseFactory>()
.InstancePerDependency());
// Create a nested lifetime scope for the web app that registers
// things as InstancePerHttpRequest, etc. Pass that scope
// as the basis for the MVC dependency resolver.
var webScope = container.BeginLifetimeScope(
b => b.RegisterType<DatabaseFactory>()
.As<IDatabaseFactory>()
.InstancePerHttpRequest());
var resolver = new AutofacDependencyResolver(webScope);
DependencyResolver.SetResolver(resolver);
如果您真的很喜欢这个选项,您可以实现一个自定义 IContainer
,它可以检测它所在的上下文并从适当的嵌套范围中解决问题。这就是 Multi-Tenancy Autofac 支持的工作原理。然而,这是一个复杂得多的解决方案,所以我不打算在这里把它全部写出来。检查 Autofac 源以获取 Multi-Tenancy 支持示例。
选项:您可以使用“最小公分母”类型的注册,例如 InstancePerDependency
或 InstancePerLifetimeScope
并跳过拥有不同的概念应用程序不同部分的生命周期。
请注意,目前,从技术上讲,InstancePerHttpRequest
和 InstancePerWebApiRequest
所做的事情 之间没有区别。它们都归结为完全相同的东西,并且可以有效地互换。 (我不能保证它永远都是那样,但我不知道为什么它需要改变。)
关于c# - 可以在注册中指定多个 Autofac 生命周期范围吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16817655/