实例范围决定了如何在同一服务的请求之间共享实例。 请注意,您应该熟悉生命周期范围的概念,以便更好地理解此处发生的情况。

当请求服务时,Autofac可以返回单个实例(单实例作用域),新实例(每个依赖作用域)或某种上下文中的单个实例,例如 线程或HTTP请求(每个生命周期范围)。

这适用于从显式Resolve()调用返回的实例以及容器内部创建的实例,以满足另一个组件的依赖关系。

选择正确的生命周期范围将有助于避免组件寿命过长或不够长的俘获依赖和其他陷阱。 开发人员需要为每个应用程序组件做出正确的选择。

1.Instance Per Dependency

每次都会返回一个新的实例,并且这是默认的生命周期。

var builder = new ContainerBuilder();

// This...
builder.RegisterType<Worker>(); // 此句代码的效果同上
builder.RegisterType<Worker>().InstancePerDependency();

当您解析每个依赖项的实例组件时,每次都会得到一个新组件。

using(var scope = container.BeginLifetimeScope())
{
for(var i = 0; i < 100; i++)
{
// Every one of the 100 Worker instances
// resolved in this loop will be brand new.
var w = scope.Resolve<Worker>();
w.DoWork();
}
}

2.Single Instance

单例,所有服务请求都将会返回同一个实例。

var builder = new ContainerBuilder();
builder.RegisterType<Worker>().SingleInstance();

当您解析单个实例组件时,无论您请求何处,都始终获得相同的实例。

// It's generally not good to resolve things from the
// container directly, but for singleton demo purposes
// we do...
var root = container.Resolve<Worker>(); // We can resolve the worker from any level of nested
// lifetime scope, any number of times.
using(var scope1 = container.BeginLifetimeScope())
{
for(var i = 0; i < 100; i++)
{
var w1 = scope1.Resolve<Worker>();
using(var scope2 = scope1.BeginLifetimeScope())
{
var w2 = scope2.Resolve<Worker>(); // root, w1, and w2 are always literally the
// same object instance. It doesn't matter
// which lifetime scope it's resolved from
// or how many times.
}
}
}

3.Instance Per Lifetime Scope

在一个嵌套语句块中,只会返回一个实例。

var builder = new ContainerBuilder();
builder.RegisterType<Worker>().InstancePerLifetimeScope();

在解决每个生命周期实例作用域组件时,每个嵌套作用域将获得一个实例(例如,每个工作单元)。

using(var scope1 = container.BeginLifetimeScope())
{
for(var i = 0; i < 100; i++)
{
// 每次从这里解析它
// 你会得到相同的实例。
var w1 = scope1.Resolve<Worker>();
}
} using(var scope2 = container.BeginLifetimeScope())
{
for(var i = 0; i < 100; i++)
{
//每次从这里解析它
//每次解析都会得到一个同样的实例,但是这个示例和上面的循环的实例不是同一个
var w2 = scope2.Resolve<Worker>();
}
}

4.Instance Per Matching Lifetime Scope

这与上面的'每个生命周期的实例范围'概念类似,但允许更精确地控制实例共享。

当您创建嵌套的生存期范围时,您可以“标记”或“命名”范围。具有每匹配生命周期范围的组件每个嵌套生命周期范围最多只有一个实例与给定名称匹配。这允许您创建一种“范围单例”,其中嵌套的生命周期范围可以在不声明全局共享实例的情况下共享某个组件的实例。

这对于特定于单个工作单元的对象是有用的,例如,一个HTTP请求,作为一个嵌套的生命周期可以创建每个工作单元。如果每个HTTP请求都创建一个嵌套的生命周期,那么每个具有每个生命周期范围的组件都将为每个HTTP请求创建一个实例。 (有关每个请求生命周期范围的更多信息。)

在大多数应用中,只有一层容器嵌套足以代表工作单元的范围。如果需要更多级别的嵌套(例如像global-> request-> transaction这样的东西),组件可以配置为使用标签在层次结构中的特定级别共享。

var builder = new ContainerBuilder();
builder.RegisterType<Worker>().InstancePerMatchingLifetimeScope("myrequest");

提供的标记值在启动时与生存期范围关联。 如果在没有正确命名的生命周期范围时尝试解析每个匹配生命周期范围的组件,则会得到一个异常。

//使用标签创建生命周期
using(var scope1 = container.BeginLifetimeScope("myrequest"))
{
for(var i = 0; i < 100; i++)
{
var w1 = scope1.Resolve<Worker>();
using(var scope2 = scope1.BeginLifetimeScope())
{
var w2 = scope2.Resolve<Worker>(); // w1和w2始终是同一个对象
       //实例,因为该组件是每个匹配生命周期范围的,
       //所以它实际上是一个单例
       //命名范围
}
}
} //使用标签创建另一个生命周期作用域
using(var scope3 = container.BeginLifetimeScope("myrequest"))
{
for(var i = 0; i < 100; i++)
{
// w3 will be DIFFERENT than the worker resolved in the
// earlier tagged lifetime scope.
var w3 = scope3.Resolve<Worker>();
using(var scope4 = scope3.BeginLifetimeScope())
{
var w4 = scope4.Resolve<Worker>(); // w3和w4始终是同一个对象,因为
       //他们在相同的标记范围内,但他们是
       //与之前的w1,w2不一样。
}
}
}
//你无法解析每个匹配生命周期的组件
//如果没有匹配的范围。
using(var noTagScope = container.BeginLifetimeScope())
{
//因为这个范围没有,所以抛出一个异常
   //有预期的标签,也没有任何父范围!
var fail = noTagScope.Resolve<Worker>();
}

5.Instance Per Request

某些应用程序类型自然适用于“请求”类型语义,例如ASP.NET Web Forms和MVC应用程序。 在这些应用程序类型中,有能力为每个请求提供一种“单例”。

通过提供众所周知的生命周期范围标记,注册便利方法以及针对常见应用程序类型的集成,每个请求的实例基于每个匹配生命周期范围的实例构建。 但在幕后,它仍然只是每个匹配生命周期范围的实例。

这意味着如果您尝试解析注册为每个请求实例但没有当前请求的组件,那么您将得到一个异常。

var builder = new ContainerBuilder();
builder.RegisterType<Worker>().InstancePerRequest();

6.Instance Per Owned

拥有的隐式关系类型创建新的嵌套生命周期作用域。 可以使用每个拥有实例的注册来将依赖关系限定到拥有的实例。

var builder = new ContainerBuilder();
builder.RegisterType<MessageHandler>();
builder.RegisterType<ServiceForHandler>().InstancePerOwned<MessageHandler>();

在这个例子中,ServiceForHandler服务将被限制在拥有的MessageHandler实例的生命周期中。

using(var scope = container.BeginLifetimeScope())
{
//消息处理程序本身以及
   //解析依赖的ServiceForHandler服务
   //在一个小小的生命周期范围内
   // “范围。” 请注意解析一个拥有的<T>
   //表示您负责处理。
var h1 = scope.Resolve<Owned<MessageHandler>>();
h1.Dispose();
}

原文:http://autofaccn.readthedocs.io/en/latest/lifetime/instance-scope.html

Autofac容器对象实例的几种生命周期类型的更多相关文章

  1. Autofac学习之三种生命周期:InstancePerLifetimeScope、SingleInstance、InstancePerDependency

    InstancePerLifetimeScope:同一个Lifetime生成的对象是同一个实例 SingleInstance:单例模式,每次调用,都会使用同一个实例化的对象:每次都用同一个对象: In ...

  2. Autofac学习之三种生命周期:InstancePerLifetimeScope、SingleInstance、InstancePerDependency 【转载】

    InstancePerLifetimeScope:同一个Lifetime生成的对象是同一个实例 SingleInstance:单例模式,每次调用,都会使用同一个实例化的对象:每次都用同一个对象: In ...

  3. Vue 实例详解与生命周期

    Vue 实例详解与生命周期 Vue 的实例是 Vue 框架的入口,其实也就是前端的 ViewModel,它包含了页面中的业务逻辑处理.数据模型等,当然它也有自己的一系列的生命周期的事件钩子,辅助我们进 ...

  4. Java对象在JVM中的生命周期

          当你通过new语句创建一个java对象时,JVM就会为这个对象分配一块内存空间,只要这个对象被引用变量引用了,那么这个对象就会一直驻留在内存中,否则,它就会结束生命周期,JVM会在合适的时 ...

  5. JAVA-JSP内置对象之session对象设置并获得session生命周期

    相关资料:<21天学通Java Web开发> session对象设置并获得session生命周期1.通过session对象的setMaxInactiveInterval()方法可以设置se ...

  6. ASP.NET Core :容器注入(二):生命周期作用域与对象释放

    //瞬时生命周期 ServiceCollection services = new ServiceCollection(); services.AddTransient<TestServiceI ...

  7. spring总结之一(spring开发步骤、bean对象的管理、bean生命周期)

    ###spring 1.概念:开源,轻量级,简化开发的企业级框架. 开源:免费,发展快. 轻量级:占内存小. 简化开发:通用的功能封装,提高程序员的开发效率.--------------------- ...

  8. 05-Vue入门系列之Vue实例详解与生命周期

    Vue的实例是Vue框架的入口,其实也就是前端的ViewModel,它包含了页面中的业务逻辑处理.数据模型等,当然它也有自己的一系列的生命周期的事件钩子,辅助我们进行对整个Vue实例生成.编译.挂着. ...

  9. 《深入Java虚拟机学习笔记》- 第7章 类型的生命周期/对象在JVM中的生命周期

    一.类型生命周期的开始 如图所示 初始化时机 所有Java虚拟机实现必须在每个类或接口首次主动使用时初始化: 以下几种情形符合主动使用的要求: 当创建某个类的新实例时(或者通过在字节码中执行new指令 ...

随机推荐

  1. Implemented the “Importance Sampling of Reflections from Hair Fibers”

      Just the indirect specular pass by importance sampling. With all layers. Manually traced by 3D Ham ...

  2. Flutter 布局控件完结篇

    本文对Flutter的29种布局控件进行了总结分类,讲解一些布局上的优化策略,以及面对具体的布局时,如何去选择控件. 1. 系列文章 Flutter 布局详解 Flutter 布局(一)- Conta ...

  3. js的深层克隆和浅层克隆代码和理解

    <script> //判断是不是原始值 //判断是数组还是对象 //建立相应的数组或对象 var obj={ name:'辣鸡', sex:'male', card:['laobi','f ...

  4. Python笔记(十六):迭代器

    (一)iterable对象和Iterator对象的区别 iterable对象(可迭代的对象):可以使用for循环,例如:字符串.列表 .字典 .集合等 Iterator对象(迭代器):除了可以用for ...

  5. 使用concurrent.futures模块中的线程池与进程池

    使用concurrent.futures模块中的线程池与进程池 线程池与进程池 以线程池举例,系统使用多线程方式运行时,会产生大量的线程创建与销毁,创建与销毁必定会带来一定的消耗,甚至导致系统资源的崩 ...

  6. CVE-2012-0158 分析

    目录 CVE-2012-0158 分析&利用 1.实验环境 2.下载poc样本 3.调试并找到漏洞触发点 4.分析漏洞触发模块及流程 5.漏洞利用 6.总结 7.参考资料 CVE-2012-0 ...

  7. vs2010 2013 2015 有用各种功能插件

    https://blog.csdn.net/daydayup_chf/article/details/80803221

  8. java学习(权限修饰符)

    Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java 支持 4 种不同的访问权限. default (即缺省,什么也不写): 在同一包内可见,不使用任何修饰符.使用对象:类. ...

  9. IntelliJ IDEA 创建maven管理的webapp项目

    因为使用框架时基本需要使用maven管理项目,所以单独写一个搭建maven项目的流程 第一步:  File-->New--Project 第二步:  选择maven框架 第三步:  输入工程id ...

  10. 用sed实现wc -w的功能

    版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖.如要转贴,必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/7663831.html 作者:窗户 Q ...