两个范围之间有什么区别?
我正在每层构建Module
(存储库,服务,MVC应用程序),但为了拥有InstancePerHttpRequest
,您需要Autofac.Mvc程序集。
我应该在我的存储库和服务层中使用哪个范围?
答案 0 :(得分:100)
InstancePerHttpRequest
和InstancePerApiRequest
基本上做同样的事情 - 您为每个离散的Web请求获得一个服务实例。我会在答案的其余部分使用InstancePerHttpRequest
,但请记住,这两个是可以互换的。
InstancePerLifetimeScope
表示将为每个请求服务的生命周期范围创建一个新的服务实例。每个Web请求都有自己的新生命周期范围,因此在实践中,这两个通常会做同样的事情。
唯一真正的区别在于,如果您在InstancePerHttpRequest
下注册了服务,并且您从另一个注册为SingleInstance
的服务请求其中一项服务。在这种情况下:
SingleInstance
组件位于 root 范围InstancePerHttpRequest
组件位于名为" AutofacWebRequest"的范围内,该范围是根范围的子 Autofac不允许从子范围解析 - 实际上SingleInstance
服务无法找到InstancePerHttpRequest
服务。
但是,如果在这种情况下您使用了InstancePerLifetimeScope
(而非InstancePerHttpRequest
),那么您的服务就可以解决。
我已经写了一篇包含可下载代码的相当详尽的文章,试图详细解释所有这些 - see here。引用文章:
这里常见的一个误解是,在WebAPI应用程序中使用InstancePerLifetimeScope注册组件意味着您的组件位于Web请求的范围内 - 即“Lifetime”指的是“Web请求的生命周期”。正如你在这里看到的,这是错误的。
组件的生命周期取决于解决方案的范围。
由于SingletonResolvable从根作用域解析其标记,因此该标记实例位于根作用域中,而不是Web请求的作用域。我之前已经说过,但我会再说一遍:这个令牌将一直存在,直到整个应用程序被处理掉(例如,IIS工作进程被回收)。从根作用域请求ScopeToken的任何内容都将被赋予对该标记的引用。
希望有所帮助 - 我很欣赏这个问题现在很老了,但它仍然非常相关!
答案 1 :(得分:8)
应用程序中唯一能够完全决定对象生命周期的地方就是组合根。
在这种情况下,您会遇到冲突 - 您有一个通用模块,无法访问MVC集成提供的扩展方法 - 但您需要访问它才能正确管理生命周期。在这种情况下,如果您的模块可以提供合理的默认值,例如InstancePerLifetimeScope
,那么这就是我在模块级别所做的。然后,让组合根覆盖该行为。在这种情况下,组合根将把生命周期更改为InstancePerHttpRequest
。由于上次注册将覆盖之前的注册,因此您应该处于良好状态。
由于以下几个原因,我实际上已经不再创建与包含给定图层的程序集共存的模块:
相反(并且在大到足以保证的项目中),我在组合根级别创建模块,因为在这个级别我明确知道它们应该如何连接在一起。有时我会创建一个包含模块的Ioc
程序集,它充当默认的组合根 - 但这通常会在“真正的”组合根(例如,拉入控制台的控制台或MVC应用程序)中被覆盖。 Ioc
汇编)。
答案 2 :(得分:2)
在Autofac per lifetime 范围是使用嵌套生命周期创建自定义范围的一般方法。
使用InstancePerLifetimeScope
为您提供每个请求范围,这会为单个请求添加组件生命周期,并在内部对此组件使用InstancePerLifetimeScrope
。
在您需要的任何地方使用InstancePerLifetimeScope
,或者如果在服务层中引用Autofac.Integration.Mvc
程序集是个问题 - 在每个请求开始时手动创建嵌套作用域并使用{{1 }}