C# Autofac - InstancePerHttpRequest 与 InstancePerLifetimeScope
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12127000/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Autofac - InstancePerHttpRequest vs InstancePerLifetimeScope
提问by Sam
What are the differences between the two scopes?
这两个范围之间有什么区别?
I am building Module(s) in each layer (Repository, Service, MVC App), but in order to have InstancePerHttpRequestyou need the Autofac.Mvc assembly.
我Module在每一层(存储库、服务、MVC 应用程序)中构建(s),但为了让InstancePerHttpRequest您需要 Autofac.Mvc 程序集。
Which scope should I be using in my Repository and Service layer?
我应该在存储库和服务层中使用哪个范围?
采纳答案by gerrod
InstancePerHttpRequestand InstancePerApiRequestessentially do the same thing - you get a single instance of your service for each discrete web request. I'll use InstancePerHttpRequestfor the rest of the answer, but keep in mind that these two are interchangeable.
InstancePerHttpRequest并且InstancePerApiRequest基本上做同样的事情 - 您为每个离散的 Web 请求获得一个服务实例。我将InstancePerHttpRequest用于其余的答案,但请记住,这两个是可以互换的。
InstancePerLifetimeScopemeans a new instance of the service will be created for every lifetime scope which asks for your service. Each web request gets its own fresh lifetime scope, so in practice, more often than not, these two will do the exact same thing.
InstancePerLifetimeScope意味着将为请求您的服务的每个生命周期范围创建一个新的服务实例。每个 Web 请求都有自己的新生命周期范围,因此在实践中,这两个请求通常会做完全相同的事情。
The only real difference comes if you have a service registered under InstancePerHttpRequestand you request one of those services from another service which is registered as a SingleInstance. In this scenario:
唯一真正的区别在于,如果您注册了一项服务,InstancePerHttpRequest并且您从另一个注册为SingleInstance. 在这种情况下:
- The
SingleInstancecomponent lives in the rootscope - The
InstancePerHttpRequestcomponent lives in a scope called "AutofacWebRequest", which is a childof the root scope
- 该
SingleInstance组件位于根范围内 - 该
InstancePerHttpRequest组件住在一个叫“AutofacWebRequest”的范围,这是一个孩子的根范围的
Autofac does not allow for resolution from child scopes - so essentially, the SingleInstanceservice cannot find the InstancePerHttpRequestservice.
Autofac 不允许从子作用域解析 - 所以本质上,该SingleInstance服务无法找到该InstancePerHttpRequest服务。
However, if in this scenario you had used InstancePerLifetimeScope(instead of InstancePerHttpRequest), then your services would resolve just fine.
但是,如果在这种情况下您使用了InstancePerLifetimeScope(而不是InstancePerHttpRequest),那么您的服务会很好地解决。
I've written up a fairly exhaustive article with downloadable code that attempts to explain all this in detail - see here. Quoting from the article:
我写了一篇相当详尽的文章,其中包含可下载的代码,试图详细解释所有这些 -请参阅此处。引自文章:
One common misconception here is that registering your component with InstancePerLifetimeScope in a WebAPI application means that your component lives in the scope of a web request – i.e. that “Lifetime” refers to “the Lifetime of the web request”. As you can see here, this is false.
The lifetime of your component is determined by the scope in which it was resolved.
Since the SingletonResolvable resolves its token from the root scope, that token instance lives in the root scope, not the scope of a web request. I've said it before, but I'll say it again: this token will live until the entire application is disposed of (e.g. the IIS worker process is recycled). Anything which asks for a ScopeToken from the root scope will be given a reference to that token.
这里的一个常见误解是,在 WebAPI 应用程序中使用 InstancePerLifetimeScope 注册您的组件意味着您的组件位于 Web 请求的范围内——即“Lifetime”指的是“Web 请求的生命周期”。正如你在这里看到的,这是错误的。
组件的生命周期由它解决的范围决定。
由于 SingletonResolvable 从根范围解析其令牌,该令牌实例位于根范围内,而不是 Web 请求的范围内。我之前说过,但我再说一遍:这个令牌将一直存在,直到整个应用程序被处理掉(例如,IIS 工作进程被回收)。任何从根范围请求 ScopeToken 的东西都将被赋予对该令牌的引用。
Hope that helps - I appreciate this question is now quite old, however its still very relevant!
希望有所帮助 - 我很欣赏这个问题现在已经很老了,但它仍然非常相关!
回答by whyleee
In Autofac per lifetimescope is a generic way to create custom scopes using nested lifetimes.
在 Autofac 中,每个生命周期范围是使用嵌套生命周期创建自定义范围的通用方法。
Using InstancePerLifetimeScopegives you per requestscope, which adds component lifetime for single request and internally uses InstancePerLifetimeScropefor this component.
UsingInstancePerLifetimeScope为您提供每个请求范围,这为单个请求增加了组件生命周期,并在内部使用InstancePerLifetimeScrope此组件。
Use InstancePerLifetimeScopeeverywhere you need this, or if it is a problem to have a reference to Autofac.Integration.Mvcassembly in your service layer - create nested scopes manually on each beginning of request and use InstancePerLifetimeScope.
InstancePerLifetimeScope在您需要的任何地方使用,或者如果Autofac.Integration.Mvc在您的服务层中引用程序集有问题- 在 request 和 use 的每个开头手动创建嵌套范围InstancePerLifetimeScope。
回答by Kaleb Pederson
The only place in your application that's completely capable of making a decision about the lifetime of an object is at the composition root.
应用程序中唯一能够完全决定对象生命周期的位置是组合根。
In this case you have a conflict -- you have a generic module that shouldn't have access to extension method provided by the MVC integration -- yet you need to have access to it in order for the lifetime to be managed properly. In this case, if your module can provide a reasonable default, like InstancePerLifetimeScope, then that's what I'd do at the module level. Then, you let the composition root override that behavior. In this case the composition root would change the lifetime to InstancePerHttpRequest. Since the last registration will override the earlier registrations, you should be in good shape.
在这种情况下,您会遇到冲突——您拥有一个不应访问 MVC 集成提供的扩展方法的通用模块——但您需要访问它才能正确管理生命周期。在这种情况下,如果您的模块可以提供合理的默认值,例如InstancePerLifetimeScope,那么这就是我在模块级别所做的。然后,您让组合根覆盖该行为。在这种情况下,组合根会将生命周期更改为InstancePerHttpRequest。由于上次注册将覆盖较早的注册,因此您应该处于良好状态。
I've actually moved away from creating modules that coexist with the assembly that contains a given layer for a couple of reasons:
由于以下几个原因,我实际上已经不再创建与包含给定层的程序集共存的模块:
- It introduces a dependency on Autofac, which I don't want except at my composition root
- It suggests that the module knows how it's lifetime should be managed, which isn't usually true. If it does, why not provide a factory or other classes which provide that lifetime management?
- 它引入了对 Autofac 的依赖,除了在我的组合根目录之外,我不想要它
- 它表明模块知道应该如何管理它的生命周期,这通常不是真的。如果是这样,为什么不提供一个工厂或其他提供生命周期管理的类?
Instead (and in projects large enough to warrant), I create the modules at the composition root level as at this level I have explicit knowledge about how they should be wired together. Sometimes I'll create an Iocassembly that contains the modules and that acts as a default composition root -- but this is often overridden at the "real" composition root (e.g., the console or MVC application that pulls in the Iocassembly).
相反(并且在足够大的项目中),我在组合根级别创建模块,因为在这个级别我对如何将它们连接在一起有明确的了解。有时我会创建一个Ioc包含模块并充当默认组合根的程序集——但这通常在“真正的”组合根(例如,拉入Ioc程序集的控制台或 MVC 应用程序)中被覆盖。

