autofac 组件的实例范围
实例范围决定如何在请求之间共享服务。
原文地址:http://docs.autofac.org/en/latest/lifetime/instance-scope.html
每个依赖一个实例
使用这个选项,每次请求服务都会返回一个新实例。使用 InstancePerDependency() 指定。这是默认选项。下面的代码,第2行和第3行是等价的。
- var builder = new ContainerBuilder();
- builder.RegisterType<Worker>();
- builder.RegisterType<Worker>().InstancePerDependency();
下面的代码,每次循环都生成一个新的实例,一共生成 100 个实例。
- using(var scope = container.BeginLifetimeScope())
- {
- for(var i = ; i < ; i++)
- {
- var w = scope.Resolve<Worker>();
- w.DoWork();
- }
- }
单个实例
使用这个选项,在根范围或嵌套范围中请求服务,都返回同一个的实例。使用 SingleInstance() 指定。
- var builder = new ContainerBuilder();
- builder.RegisterType<Worker>().SingleInstance();
下面的代码,w1 和 w2 始终是同一个对象,100 次循环只有一个 Worker 类的实例。
- using(var scope1 = container.BeginLifetimeScope())
- {
- for(var i = ; i < ; i++)
- {
- var w1 = scope1.Resolve<Worker>();
- using(var scope2 = scope1.BeginLifetimeScope())
- {
- var w2 = scope2.Resolve<Worker>();
- }
- }
- }
每个生命周期范围一个实例
使用这个选项,在特定的 ILifetimeScope 中请求服务,只返回一个实例。使用 InstancePerLifetimeScope() 指定。下面的代码中,scope1 中的 100 次 w1 是同一个对象,scope2 中的 100 次 w2 是同一个对象,但是 w1 和 w2 不是同一个对象。
- var builder = new ContainerBuilder();
- builder.RegisterType<Worker>().InstancePerLifetimeScope();
- using(var scope1 = container.BeginLifetimeScope())
- {
- for(var i = ; i < ; i++)
- {
- var w1 = scope1.Resolve<Worker>();
- }
- }
- using(var scope2 = container.BeginLifetimeScope())
- {
- for(var i = ; i < ; i++)
- {
- var w2 = scope2.Resolve<Worker>();
- }
- }
每个匹配的生命周期范围一个实例
类似于上面【每个生命周期范围一个实例】,但可以提供更多控制。使用此选项,允许为 ILifetimeScope 对象提供“标记”。在标记匹配的范围中只有一个实例。使用 InstancePerMatchingLifetimeScope() 方法指定。
- var builder = new ContainerBuilder();
- builder.RegisterType<Worker>().InstancePerMatchingLifetimeScope("x");
下面的代码中,w1 和 w2 相同,w3 和 w4 相同,但 w1 和 w3 不同。
- using(var scope1 = container.BeginLifetimeScope("x"))
- {
- for(var i = ; i < ; i++)
- {
- var w1 = scope1.Resolve<Worker>();
- using(var scope2 = scope1.BeginLifetimeScope())
- {
- var w2 = scope2.Resolve<Worker>();
- }
- }
- }
- using(var scope3 = container.BeginLifetimeScope("x"))
- {
- for(var i = ; i < ; i++)
- {
- var w3 = scope3.Resolve<Worker>();
- using(var scope4 = scope1.BeginLifetimeScope())
- {
- var w4 = scope4.Resolve<Worker>();
- }
- }
- }
解析时必须提供提供合适的标记,以下代码会抛出异常。
- using(var noTagScope = container.BeginLifetimeScope())
- {
- var fail = noTagScope.Resolve<Worker>();
- }
每个请求一个实例
有些应用程序天然具有【请求】语义,例如 ASP.NET MVC 或 WebForm 应用程序。【每个请求一个实例】在【每个匹配的生命周期范围一个实例】基础上,通过提供范围标记,注册函数和常见类型集成实现。本质上是【每个匹配的生命周期范围一个实例】。
- var builder = new ContainerBuilder();
- builder.RegisterType<Worker>().InstancePerRequest();
ASP.NET Core 使用【每个生命周期范围一个实例】,而不是【每个请求一个实例】。
每个 Owned 一个实例
Owned<T> 隐式关联类型创建嵌套的生命周期范围。使用 instance-per-owned 注册,可将依赖限定在 owned 实例中。
- var builder = new ContainerBuilder();
- builder.RegisterType<MessageHandler>();
- builder.RegisterType<ServiceForHandler>().InstancePerOwned<MessageHandler>();
本例中 ServiceForHandler 服务会限制在 MessageHandler 实例范围内。
- using(var scope = container.BeginLifetimeScope())
- {
- // MessageHandler 和附属的 ServiceForHandler
// 在 scope 下面的一个微型的 lifetime scope 中。
// 解析 Owned<T> 需要程序员负责执行清理工作。- var h1 = scope.Resolve<Owned<MessageHandler>>();
- h1.Dispose();
- }
线程范围
Autofac 可以强制使A线程的对象不满足B线程的依赖。
- var builder = new ContainerBuilder();
- builder.RegisterType<MyThreadScopedComponent>()
- .InstancePerLifetimeScope();
- var container = builder.Build();
然后让每个创建自己的 lifetime scope
- void ThreadStart()
- {
- using (var threadLifetime = container.BeginLifetimeScope())
- {
- var thisThreadsInstance = threadLifetime.Resolve<MyThreadScopedComponent>();
- }
- }
重要:在多线程场景下,要小心不要将父范围清理掉。否则,派生线程中的子范围将无法解析服务。
每个线程都将有自己的 MyThreadScopedComponent 实例,本质上是生命周期范围内的单例。范围内的实例不会提供到外部,因此很容易保持线程间的组件隔离。
通过添加 ILifetimeScope 参数,可将父范围注入到生成线程的代码中,Autofac 会将当前范围自动注入,接下来可以使用它创建嵌套范围。
- public class ThreadCreator
- {
- private ILifetimeScope _parentScope;
- public ThreadCreator(ILifetimeScope parentScope)
- {
- this._parentScope = parentScope;
- }
- public void ThreadStart()
- {
- using (var threadLifetime = this._parentScope.BeginLifetimeScope())
- {
- var thisThreadsInstance = threadLifetime.Resolve<MyThreadScopedComponent>();
- }
- }
- }
如果想进一步控制,可以使用【每个匹配的生命周期范围一个实例】将线程范围的组件同内部生命周期范围关联起来,这个方式的效果如图:
图中的"Context"是 BeginLifetimeScope 方法创建的生命周期范围。
autofac 组件的实例范围的更多相关文章
- Autofac - 组件
快到年终了, 最近项目比较悠闲, 就想总结下, 项目中所使用到的一些技术, 以及使用方法. 之前有写过Dapper以及Dapper的一个扩展, 这些也是项目中使用过的. 算是一个温故而知新吧. 代码: ...
- Autofac容器对象实例的几种生命周期类型
实例范围决定了如何在同一服务的请求之间共享实例. 请注意,您应该熟悉生命周期范围的概念,以便更好地理解此处发生的情况. 当请求服务时,Autofac可以返回单个实例(单实例作用域),新实例(每个依赖作 ...
- SQL Server COM 组件创建实例失败
SQL Server COM 组件创建实例失败 SQL2008数据库总会出现从 IClassFactory 为 CLSID 为 {17BCA6E8-A95D-497E-B2F9-AF6AA4759 ...
- 从ICassFactory为CLSID为{17BCA6E8-A950-497E-B2F9-AF6AA475916F}的COM组件创建实例失败问题解决方法
从ICassFactory为CLSID为{17BCA6E8-A950-497E-B2F9-AF6AA475916F}的COM组件创建实例失败,原因是出现以下错误:c001f011.(Microsoft ...
- 从ICassFactory为CLSID为{17BCA6E8-A950-497E-B2F9-AF6AA475916F}的COM组件创建实例失败,原因是出现以下错误:c001f011.(Microsoft.Server.manageDTS
从ICassFactory为CLSID为{17BCA6E8-A950-497E-B2F9-AF6AA475916F}的COM组件创建实例失败,原因是出现以下错误:c001f011.(Microsoft ...
- React 深入系列1:React 中的元素、组件、实例和节点
文:徐超,<React进阶之路>作者 授权发布,转载请注明作者及出处 React 深入系列,深入讲解了React中的重点概念.特性和模式等,旨在帮助大家加深对React的理解,以及在项目中 ...
- Vue组件开发实例(详细注释)
Vue组件开发实例: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...
- COM 组件创建实例失败,原因是出现以下错误: c001f011 (Microsoft.SqlServer.ManagedDTS)
从 IClassFactory 为 CLSID 为 {AA40D1D6-CAEF-4A56-B9BB-D0D3DC976BA2} 的 COM 组件创建实例失败,原因是出现以下错误: c001f011. ...
- vue第六单元(vue的实例和组件-vue实例的相关属性和方法-解释vue的原理-创建vue的组件)
第六单元(vue的实例和组件-vue实例的相关属性和方法-解释vue的原理-创建vue的组件) #课程目标 掌握vue实例的相关属性和方法的含义和使用 了解vue的数据响应原理 熟悉创建组件,了解全局 ...
随机推荐
- 【MySql】查询数据库中所有表及列的信息
SELECT TABLE_NAME, -- 表名 COLUMN_NAME, -- 字段名 DATA_TYPE, -- 字段类型 COLUMN_COMMENT -- 字段注释 FROM INFORMAT ...
- Windows 7 上安装Visual Studio 2015 失败解决方案
安装之前先要看看自己的系统支不支持,具体的可以看:https://www.visualstudio.com/en-us/visual-studio-2015-system-requirements-v ...
- 【Win10】UAP/UWP/通用 开发之 x:Bind
[Some information relates to pre-released product which may be substantially modified before it's co ...
- 【腾讯Bugly干货分享】程序员们也该知道的事——“期权和股票”
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/pfj9NLLuKYAfJJF84R9WAw 作者:B ...
- H5嵌入原生开发小结----兼容安卓与ios的填坑之路
一开始听说开发H5,以为就是做适配现代浏览器的移动网页,心想不用管IE了,欧也.到今天,发现当初too young too simple,兼容IE和兼容安卓与IOS,后者让你更抓狂.接下来数一下踩过的 ...
- 实现了一个百度首页的彩蛋——CSS3 Animation简介
在百度搜索中有这样一个彩蛋:搜索“旋转”,“跳跃”,“反转”等词语,会出现相应的动画效果(搜索“反转”后的效果).查看源码可以发现,这些效果正是通过CSS3的animation属性实现的. 实现这个彩 ...
- 提高代码质量系列之二:重构小技巧——if篇
前言: if,相信是童鞋们使用的最频繁的关键字了,而且很多时候,我们使用的if都是在无意识的状态下随手而为.键入if,两下回车(我使用了resharper,可以自动编排if的格式),再信手写下我们需要 ...
- ABP框架 - 集成OWIN
文档目录 如果你在应用中同时使用Asp.net Mvc和Asp.net Web API,你需要在你的项目里添加Abp.Owin的nuget包(通常是Web项目)然后在你的OWIN的Startup文件里 ...
- Memcached和Redis比较
一.存储 Memcached基本只支持简单的key-value存储方式.Redis除key-value之外,还支持list,set,sorted set,hash等数据结构:Redis支持数据的备份, ...
- 在linux平台实现atosl
➠更多技术干货请戳:听云博客 序言 怎么在linux 平台下实现一个类似于mac 平台下的 atos 工具( iOS 符号化解析)? 分析问题 在github上找到了几年前的开源实现,[https:/ ...