.net core的依赖注入你了解吗
1.ServiceCollection(依赖注入的容器)
ServiceCollection:ICollection<ServiceDescriptor>作为依赖注入的容器,它存在一个List<ServiceDescriptor>用来存放所有的注入到容器中的类型
这里以注入单例模式执行过程为例为例:
2.ServiceDescriptor(注入服务描述器)
private ServiceDescriptor(Type serviceType, ServiceLifetime lifetime)
{
this.Lifetime = lifetime;
this.ServiceType = serviceType;
}
//标准的注入
public ServiceDescriptor(Type serviceType, Type implementationType, ServiceLifetime lifetime) : this(serviceType, lifetime)
{
if (serviceType == null) {throw new ArgumentNullException("serviceType");}
if (implementationType == null) {throw new ArgumentNullException("implementationType"); }
this.ImplementationType = implementationType;
}
//Singleton模式
public ServiceDescriptor(Type serviceType, object instance) : this(serviceType, ServiceLifetime.Singleton)
{
//校验省略
this.ImplementationInstance = instance;
}
//工厂模式,通过ServiceProvider的Func注入
public ServiceDescriptor(Type serviceType, Func<IServiceProvider, object> factory, ServiceLifetime lifetime) : this(serviceType, lifetime)
{//校验省略
this.ImplementationFactory = factory;
}
3.ServiceProvider(实例化器)
var provider = services.BuildServiceProvider();
以Transient实例化详细执行流程如下图:
var orderService = provider.GetService<IOrderService>();
Singleton,Scope,Transient三种模式下的产生对象实例的流程如下:
4.IServiceScope
创建作用域,也就是创建子容器
单例模式是在Root容器下的,只能程序停止时释放,Transient模式,每次都会产生新的实例,所以两者应用不多。我们可以使用Scope的实例测试。
1.准备服务类
public interface IOrderService
{
}
public class DisposableOrderService : IOrderService, IDisposable
{
public void Dispose()
{
Console.WriteLine(#34;DisposableOrderService Disposed:{this.GetHashCode()}");
}
}
2.注入为Scope
services.AddScoped<IOrderService, DisposableOrderService>();
3.1调用
[HttpGet]
public int Get(
[FromServices] IOrderService aaa,
[FromServices] IOrderService bbb,
[FromServices]IHostApplicationLifetime hostApplicationLifetime,
[FromQuery]bool stop = false)
{
return 1;
}
【结果,只会打印一次,被释放的信息,因为aaa,bbb是同一个实例】
3.2 新建scope调用
[HttpGet]
public int Get(
[FromServices] IOrderService aaa,
[FromServices] IOrderService bb,
[FromServices]IHostApplicationLifetime hostApplicationLifetime,
[FromQuery]bool stop = false)
{
using (IServiceScope scope = HttpContext.RequestServices.CreateScope())
{
var service = scope.ServiceProvider.GetService<IOrderService>();
}
return 1;
}
【结果,会打印两次,被释放的信息。因为在scope内,相当于创建了一个子容器,重新创建一个是实例】
5.容器使用注意事项
1.容器会管理释放自己创建的对象,所以我们不要手动创建对象,然后放入容器。如果实现了IDisable接口,容器会帮助我们管理生命周期,调用Dispose方法。
只有Singleton接口可以直接传入一个new 的对象,其他两个接口的工厂模式和类型注入的模式的效果时一样的
1.创建的实例由容器控制释放
service.AddSignleton<IorderService,Orderservice>();
2.实例的生命周期不由容器控制释放
service.AddSingleton(new OrderService()));
2.单例是注入到应用程序的根容器(Root)中,根容器是伴随整个应用程序存在的。如果使用根容器获取Transient对象,那么将会永远存在整个应用程序周期中,不会释放。所以不要在跟容器中获取Transient对象
//跟容器是存放单例模式的,如果通过根容器获取临时对象,临时对象是不会被释放的。ApplicationService就是根容器
app.ApplicationService.GetService<IOrderService>();
3.ServiceCollection支持一个接口多个实现同时注入。
4.如果是在整个类中使用的对象,可以使用构造函数注入,如果仅仅是某个方法使用,那么可以通过属性标签的方式注入[FromService]
相关文章
- 网络爬虫:数据抓取的几种方法
- 计算机信息系统集成服务合同(中英文对照)
- 3D 渲染视频带你游览苹果"太空船"新总部园区 ...
- 微软发布SQL Server 2012 Service Pack 2
- 将数据从 MySQL 导出到 SQL Server
- Sugon and Hygon Announce Strategic Restructuring to Strengthen China's IT Industry Leadership
- 闪送如何授权并无需API集成连接其他系统
- 工业私有云如何安装PlantPAX
- (1图)美军:全球信息基础设施
- 隐形触手无处不在!智能家居、物联网:Java正在悄悄渗透你的生活