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