摘要
C#中提供了三种不同的依赖注入方式,分别是AddScoped、AddTransient和AddSingleton。每种依赖注入方式都有其独特的生命周期,在实际使用中,您可以根据需要选择不同的依赖注入方式。需要注意的是,在使用依赖注入时,您需要考虑到每种方式的生命周期和可能带来的问题,例如内存泄漏和线程安全性等。因此,在编写代码时,您需要仔细考虑您所使用的依赖注入方式,并确保它们在正确的情况下工作。
正文
试一下AddTransient
有需要的时候都会创建一个新的。
static void Main(string[] args)
{
ServiceCollection services = new ServiceCollection();
services.AddTransient<Plc>();
using (ServiceProvider sp = services.BuildServiceProvider())
{
Plc plc= sp.GetService<Plc>();
plc.Name = "S71200";
plc.Description = "SIEMENS";
plc.Read("DB0.0");
Plc plc1=sp.GetService<Plc>();
Console.WriteLine(object.ReferenceEquals(plc, plc1));
};
}
试一下AddScoped
同一个scope下面只会创建一次
static void Main(string[] args)
{
ServiceCollection services = new ServiceCollection();
services.AddScoped<Plc>();
using (ServiceProvider sp = services.BuildServiceProvider())
{
Plc plc = null;
using (IServiceScope scope = sp.CreateScope())
{
plc = scope.ServiceProvider.GetService<Plc>();
plc.Name = "S71200";
plc.Description = "SIEMENS";
plc.Read("DB0.0");
Plc plc1 = scope.ServiceProvider.GetService<Plc>();
plc1.Name = "S71500";
plc1.Read("DB0.0");
plc.Read("DB0.0");
Console.WriteLine(object.ReferenceEquals(plc, plc1));
}
using (IServiceScope scope1 = sp.CreateScope())
{
Plc plc1 = scope1.ServiceProvider.GetService<Plc>();
plc1.Name = "S71500-1";
plc1.Read("DB0.0");
plc.Read("DB0.0");
Console.WriteLine(object.ReferenceEquals(plc, plc1));
}
};
}
AddSingleton
单例模式,不管哪一个类需要这个依赖项,这个对象在整个系统中只会有一个实例。
static void Main(string[] args)
{
ServiceCollection services = new ServiceCollection();
services.AddSingleton<Plc>();
using (ServiceProvider sp = services.BuildServiceProvider())
{
Plc plc = sp.GetService<Plc>();
plc.Name = "S71200";
plc.Description = "SIEMENS";
plc.Read("DB0.0");
Plc plc1 = sp.GetService<Plc>();
plc1.Name = "S71500";
plc1.Read("DB0.0");
plc.Read("DB0.0");
Console.WriteLine(object.ReferenceEquals(plc, plc1));
};
}
生命周期的选择
如果类无状态,建议为Singleton;如果类有状态,且有Scope:控制,建议为Scoped,因为通常这种Scope控制下的代码都是运行在同一个线程中的,没有并发修改的问题;在使用Transient的时候要谨慎。