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

需要安装两个依赖包

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

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

Part 1 : AddTransient AddScoped AddSingleton

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

  public static class Demo
{
public interface IAccount { }
public interface IMessage { }
public interface ITool { }
public class Base
{
public Base()
{
Console.WriteLine($"{GetType().Name} Created");
}
}
public class Account : Base,IAccount { }
public class Message : Base, IMessage { }
public class Tool : Base, ITool { } public static void Run()
{
Console.WriteLine("Run Method Begin...");
//root provider
var rootProvider = new ServiceCollection()
.AddTransient<IAccount, Account>()
.AddScoped<IMessage, Message>()
.AddSingleton<ITool, Tool>()
.BuildServiceProvider();
//create child provider
var childProvider1 = rootProvider.CreateScope().ServiceProvider;
var childProvider2 = rootProvider.CreateScope().ServiceProvider; GetService<IAccount>(childProvider1);
GetService<IMessage>(childProvider1);
GetService<ITool>(childProvider1);
Console.WriteLine();
GetService<IAccount>(childProvider2);
GetService<IMessage>(childProvider2);
GetService<ITool>(childProvider2);
Console.WriteLine("Run Method End..."); } public static void GetService<T>(IServiceProvider serviceProvider)
{
serviceProvider.GetService<T>();
serviceProvider.GetService<T>();
} }

调用Demo.Run() 输出结果

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

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

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

Part 2 : IDisposable

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

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

public class Base : IDisposable
{
public Base()
{
Console.WriteLine($"{GetType().Name} Created");
} public void Dispose()
{
Console.WriteLine($"{GetType().Name} Disposed"
);
}

}

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

public static void Run()
{
//root provider
using (ServiceProvider root = new ServiceCollection()
.AddTransient<IAccount, Account>()
.AddScoped<IMessage, Message>()
.AddSingleton<ITool, Tool>()
.BuildServiceProvider())
{
using (var scope = root.CreateScope())
{
var child = scope.ServiceProvider;
child.GetService<IAccount>();
child.GetService<IMessage>();
child.GetService<ITool>();
Console.WriteLine("Child provider begin dispose");
}
Console.WriteLine("Child provider disposed ");
Console.WriteLine("Root provider begin dispose "); }
Console.WriteLine("Root provider disposed ");
}

测试结果

Account Created
Message Created
Tool Created
Child provider begin dispose
Message Disposed
Account Disposed
Child provider disposed

Root provider begin dispose
Tool Disposed
Root provider disposed

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

最新文章

  1. hadoop拾遗(一)---- 避免切分map文件
  2. XoftSpy 4.13的注册算法分析
  3. 静态Web开发 DOM
  4. python 中对list做减法操作
  5. KVO奥秘
  6. Spring IOC之依赖
  7. MyBatis 笔记总结
  8. JavaScript判断变量数据类型
  9. freemarker之list遍历(八)
  10. 温故而知新--hashtable
  11. java开发中几种常见的线程池
  12. UML在代码中的展现
  13. docker 笔记
  14. 【C#加深理解系列】(二)序列化
  15. Ruby数组(1):基本用法
  16. 学习Acegi应用到实际项目中(11)- 切换用户
  17. maven发布jar包到nexus
  18. 洛谷P4593 [TJOI2018]教科书般的亵渎(拉格朗日插值)
  19. jcmd
  20. HBase的Shell命令和JavaAPI

热门文章

  1. python-实现顺序栈
  2. Kafka又出问题了!
  3. Spring Boot MVC 单张图片和多张图片上传 和通用文件下载
  4. Dcoker-搭建日志监控系统
  5. CVE-2020-1472 Zerologon
  6. [Fundamental of Power Electronics]-PART I-3.稳态等效电路建模,损耗和效率-3.3 等效电路模型的构建
  7. AI数学基础之:确定图灵机和非确定图灵机
  8. 算法:第一节课Master定理
  9. 逆向初级-PE(五)
  10. Mysql无法通过临时密码访问