依赖注入AddScoped()方法
Singleton和transient两种依赖注入方式比较容易懂。今天专门讲一下依赖注入Scope域的概念。
直接上例子:
using System;
using Microsoft.Extensions.DependencyInjection;
namespace vscode_test5
{
interface IMyInfo
{
void PrintID();
}
public class MyInfo:IMyInfo,IDisposable
{
private string id;
public MyInfo(string guid)
{
id = guid;
}
public MyInfo():this(Guid.NewGuid().ToString())
{
}
public void PrintID()
{
System.Console.WriteLine(id);
}
public void Dispose()
{
System.Console.WriteLine($"disposed:{id}");
}
}
class Program
{
static void Main(string[] args)
{
IServiceCollection s = new ServiceCollection();
s.AddScoped(typeof(IMyInfo), typeof(MyInfo));
IServiceProvider sp = s.BuildServiceProvider(); // 这叫 “根provider”
using(IServiceScope iss1 = sp.CreateScope()) // 创建第一个Scope域,此时会根据“根provider”生成一个新的provider副本
{
IMyInfo mf1 = iss1.ServiceProvider.GetService<IMyInfo>();//从副本中获取IMyInfo服务
mf1.PrintID();
IMyInfo mf2= iss1.ServiceProvider.GetService<IMyInfo>();//从副本中获取IMyInfo服务
mf2.PrintID();
}
using(IServiceScope iss2 = sp.CreateScope())
{
IMyInfo mf1 = iss2.ServiceProvider.GetService<IMyInfo>();//从副本中获取IMyInfo服务
mf1.PrintID();
IMyInfo mf2= iss2.ServiceProvider.GetService<IMyInfo>();//从副本中获取IMyInfo服务
mf2.PrintID();
}
using(IServiceScope iss3 = sp.CreateScope())
{
IMyInfo mf1 = iss3.ServiceProvider.GetService<IMyInfo>();//从副本中获取IMyInfo服务
mf1.PrintID();
IMyInfo mf2= iss3.ServiceProvider.GetService<IMyInfo>();//从副本中获取IMyInfo服务
mf2.PrintID();
}
}
}
}
执行结果:
8a77cb3e-f675-40d1-bd72-666e77630f40
8a77cb3e-f675-40d1-bd72-666e77630f40
disposed:8a77cb3e-f675-40d1-bd72-666e77630f40
40baa6e5-9d05-4838-ad1c-152d30290909
40baa6e5-9d05-4838-ad1c-152d30290909
disposed:40baa6e5-9d05-4838-ad1c-152d30290909
f0cfd64d-f0f8-437b-95d5-3830913d0bef
f0cfd64d-f0f8-437b-95d5-3830913d0bef
disposed:f0cfd64d-f0f8-437b-95d5-3830913d0bef
每个using语句会创建一个IServiceScope域,在这个区域内取两次都是一样的值。using语句之外,会自动执行相应服务的Dispose()方法,这是由于using语句块之外会自动释放所获取的Scoped服务。当然,服务实现是允许不实现IDisposable接口的。
总之这个using块内IServiceScoped所在的生存周期,就是Scoped服务的生存周期。