首先我们在VS2019中创建一个.NET Core的控制台程序,方便演示;

需要安装两个依赖包

Microsoft.Extensions.DependencyInjection 依赖注入对象的具体实现

Microsoft.Extensions.DependencyInjection.Abstractions 依赖注入对象的抽象

Part 1 : AddTransient AddScoped AddSingleton

话不多说,看以下Demo的代码以及运行结果

  1. public static class Demo
  2. {
  3. public interface IAccount { }
  4. public interface IMessage { }
  5. public interface ITool { }
  6. public class Base
  7. {
  8. public Base()
  9. {
  10. Console.WriteLine($"{GetType().Name} Created");
  11. }
  12. }
  13. public class Account : Base,IAccount { }
  14. public class Message : Base, IMessage { }
  15. public class Tool : Base, ITool { }
  16.  
  17. public static void Run()
  18. {
  19. Console.WriteLine("Run Method Begin...");
  20. //root provider
  21. var rootProvider = new ServiceCollection()
  22. .AddTransient<IAccount, Account>()
  23. .AddScoped<IMessage, Message>()
  24. .AddSingleton<ITool, Tool>()
  25. .BuildServiceProvider();
  26. //create child provider
  27. var childProvider1 = rootProvider.CreateScope().ServiceProvider;
  28. var childProvider2 = rootProvider.CreateScope().ServiceProvider;
  29.  
  30. GetService<IAccount>(childProvider1);
  31. GetService<IMessage>(childProvider1);
  32. GetService<ITool>(childProvider1);
  33. Console.WriteLine();
  34. GetService<IAccount>(childProvider2);
  35. GetService<IMessage>(childProvider2);
  36. GetService<ITool>(childProvider2);
  37. Console.WriteLine("Run Method End...");
  38.  
  39. }
  40.  
  41. public static void GetService<T>(IServiceProvider serviceProvider)
  42. {
  43. serviceProvider.GetService<T>();
  44. serviceProvider.GetService<T>();
  45. }
  46.  
  47. }

调用Demo.Run() 输出结果

  1. Run Method Begin...
  2. Account Created
  3. Account Created
  4. Message Created
  5. Tool Created
  6. Account Created
  7. Account Created
  8. Message Created
  9. Run Method End...
  1. 调用GetService<T>方法获取实例进行实例的创建,AccountMessageTool都继承了Base类,因此在被创建时,会调用Base类的构造函数;
  1. AddTransient => 每次请求都会创建一个新的实例
  1. 可以看到子容器childProvider1 Account对象被创建了两次,因为可以看出AddTransient每次请求时都会创建一个新的实例;
  1. AddScoped => 同一个请求中返回同一个实例

    在子容器的作用域中进行查找,同一个子容器中只会创建一次;所以childProvider1中调用两次GetService()方法只创建一次实列;
  1. childProvider2也只创建了一次Message

    AddSingleton => 整个应用程序只会创建一次;单例永远从根容器rootProvider中查找
    Tool 因为是Singleton 类型,因此整个程序中只创建了一次;

Part 2 : IDisposable

第二部分我们来看看创建的这些对象是何时进行释放的

在以上的代码中,将Base类实现IDisposable接口

  1. public class Base : IDisposable
  2. {
  3. public Base()
  4. {
  5. Console.WriteLine($"{GetType().Name} Created");
  6. }
  7.  
  8. public void Dispose()
  9. {
  10. Console.WriteLine($"{GetType().Name} Disposed");
  11. }
  12. }

在Run方法中使用Using来测试结果:

  1. public static void Run()
  2. {
  3. //root provider
  4. using (ServiceProvider root = new ServiceCollection()
  5. .AddTransient<IAccount, Account>()
  6. .AddScoped<IMessage, Message>()
  7. .AddSingleton<ITool, Tool>()
  8. .BuildServiceProvider())
  9. {
  10. using (var scope = root.CreateScope())
  11. {
  12. var child = scope.ServiceProvider;
  13. child.GetService<IAccount>();
  14. child.GetService<IMessage>();
  15. child.GetService<ITool>();
  16. Console.WriteLine("Child provider begin dispose");
  17. }
  18. Console.WriteLine("Child provider disposed ");
  19. Console.WriteLine("Root provider begin dispose ");
  20.  
  21. }
  22. Console.WriteLine("Root provider disposed ");
  23. }

测试结果

  1. Account Created
  2. Message Created
  3. Tool Created
  4. Child provider begin dispose
  5. Message Disposed
  6. Account Disposed
  7. Child provider disposed
  8. Root provider begin dispose
  9. Tool Disposed
  10. Root provider disposed

可以看出 AddTransient 和 AddScoped 在使用完child容器后,就调用了Base的 Dispose() ;而 AddSingle则在使用完root容器后再释放的;

.NET Core 对象( Transient、Scope、Singleton )生命周期详解 (对象创建以及释放)的更多相关文章

  1. ASP.NET生命周期详解

    最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...

  2. ASP.NET生命周期详解 [转]

    最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...

  3. ASP.NET生命周期详解(转)

    看到好文章需要分享. 最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多 ...

  4. React—组件生命周期详解

    React—组件生命周期详解 转自 明明的博客  http://blog.csdn.net/slandove/article/details/50748473 (非原创) 版权声明:转载请注明出处,欢 ...

  5. ASP.NT运行原理和页面生命周期详解及其应用

    ASP.NT运行原理和页面生命周期详解及其应用 1. 下面是我画的一张关于asp.net运行原理和页面生命周期的一张详解图.如果你对具体不太了解,请参照博客园其他帖子.在这里我主要讲解它的实际应用.  ...

  6. Android之Activity生命周期详解

    Activity的生命周期方法: onCreate()--->onStart()--->onResume()--->onPause()--->onStop()--->on ...

  7. Spring IOC -bean对象的生命周期详解

    生命周期执行的过程如下:1) spring对bean进行实例化,默认bean是单例2) spring对bean进行依赖注入3) 如果bean实现了BeanNameAware接口,spring将bean ...

  8. Spring Bean的生命周期详解(转)

    Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring ...

  9. JSP和selevt 生命周期详解(JSP的生命周期和select很像,jsp底层就是一个selevt)

    JSP: JSP的生命周期指从创建到销毁的整个过程.分为以下几个阶段: 1:编译阶段:servlet引擎编译servlet源文件,生成servlet类.当浏览器请求JSP页面时,JSP引擎会首先去检查 ...

随机推荐

  1. CentOS 7 卸载 OpenJDK 安装 OracleJDK

    查看 JDK 安装版本 java -version java version 1.7.0_51 OpenJDK Runtime Environment ( rhel-2.4.5.5.el7-x86_6 ...

  2. ABP 适用性改造 - 精简 ABP CLI 生成的项目结构

    Overview 不管是公司或者个人都会有不同的开发习惯,通过建立项目模板,既可以使开发人员聚焦于业务功能的开发,也可以在一定程度上统一不同开发人员之间的开发风格.在使用 ABP 框架的过程中,对于 ...

  3. SqlServer视图的创建与使用

    SqlServer系列之视图的创建与使用: 什么是视图? 视图的概述 在数据查询中,可以看到数据表设计过程中,考虑到数据的冗余度低.数据一致性等问题,通常对数据表的设计要满足范式的要求,因此也会造成一 ...

  4. [矩阵乘法]裴波拉契数列II

    [ 矩 阵 乘 法 ] 裴 波 拉 契 数 列 I I [矩阵乘法]裴波拉契数列II [矩阵乘法]裴波拉契数列II Description 形如 1 1 2 3 5 8 13 21 34 55 89 ...

  5. Python数据分析入门(十七):绘制条形图

    条形图的绘制方式跟折线图非常的类似,只不过是换成了plt.bar方法.plt.bar方法有以下常用参数: x:一个数组或者列表,代表需要绘制的条形图的x轴的坐标点. height:一个数组或者列表,代 ...

  6. .NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决

    前言: 前段时间在对接第三方接口的时候发生了一个非常奇葩的问题,就是使用 .NET Framework 4.6 HttpWebRequest进行网络请求的相关问题.背景,关于调用第三方的接口都是使用使 ...

  7. 前端 JS 问题记录

    立即执行函数 !function(){}() function 前面增加符号 ! ~ + - 之类,都是告诉浏览器自动执行这个匿名函数,因为这些符号的运算级别都是高的 (function(){... ...

  8. day19.进程通信与线程1

    1 进程Queue介绍 1 进程间数据隔离,两个进程进行通信,借助于Queue 2 进程间通信:IPC -借助于Queue实现进程间通信 -借助于文件 -借助于数据库 -借助于消息队列:rabbitm ...

  9. JavaScript遍历对象方法总结

    前言 本篇内容将按照下图展开: 遍历Object Object最常见的遍历方法方法就是使用for...in...,但其有一定的局限性,比如只能遍历可枚举属性.虽然Object无法直接使用for循环和f ...

  10. 什么时候选择mmap而非read?

    mmap 和 read 系统流程 在linux文件系统中,通常使用open(), read()读取文件,但操作系统同样提供了mmap()作为读取文件的方式,而这两者有什么不同呢?什么时候用read() ...