一、依赖注入核心组件包:
• Microsoft.Extensions.DependencyInjection.Abstractions
• Microsoft.Extensions.DependencyInjection
使用接口实现分离模式实现,核心类包括:
• IServiceCollection --负责服务的注册;
• ServiceDescriptor --每一个服务注册的信息;
• IServiceProvider --服务具体容器,由 ServiceCollection Build 构建;
• IServiceScope --表示一个子容器的生命周期;
asp.net core 内置生命周期(ServiceLifetime):
• 单例 Singleton,在整个根容器的生命周期内都是单例模式(全局范围);
• 作用域 Scoped,在容器(或子容器)的生存周期内,若容器释放掉对象也随即释放,同时在容器(或局部作用域)范围内能得到一个单例模式;
• 瞬时(暂时)Transient ,每一次从容器获取对象时都可以得到一个全新的对象;
二、服务注册的几种方式:
在 Startup.cs 文件中,Startup.ConfigureServices 中有如下几种服务注册方式:
1.常规服务注册:
#region 注册不同生命周期的服务
services.AddSingleton<IMySingletonService, MySingletonService>();
services.AddScoped<IMyScopedService, MyScopedService>();
services.AddTransient<IMyTransientService, MyTransientService>();
#endregion
2.常规服务的“花式”注册:
services.AddSingleton<IOrderService>(new OrderService()); //直接注入实例
//同接口(IOrderService)不同实例(OrderServiceEx,OrderService)注册
services.AddSingleton<IOrderService, OrderServiceEx>();
services.AddSingleton<IOrderService, OrderService>();
//匿名方式注册,可实现具体服务拦截
services.AddSingleton<IOrderService>(serviceProvider =>
{
return new OrderServiceEx(); //serviceProvider 对象可用
});
services.AddScoped<IOrderService>(serviceProvider =>
{
return new OrderServiceEx();
});
3.尝试(或试图)注册:
services.TryAddSingleton<IOrderService, OrderServiceEx>(); //服务被注册就不是再次注册,反之就注册;
//相同类型的服务接口,如果实现不同即可注册,实现相同就不会注册
services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>());
services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService>(new OrderServiceEx()));
services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService>(p =>
{
return new OrderServiceEx();
}));
//尝试或试图注册的好处:避免重复的服务接口注册或者控制同接口不同实现的服务注册;
4.移除和替换注册:
services.Replace(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>()); //指定原有接口服务的注册,替换(或更改)为现有接口服务实现;
services.RemoveAll<IOrderService>(); //移除所有的接口服务注册的实例;
5.泛型模板模板注册:
services.AddSingleton(typeof(IGenericService<>), typeof(GenericService<>));
//使用方式,Controller构造函数注入
IOrderService _orderService;
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger, IOrderService orderService, IGenericService<IOrderService> genericService)
{
_orderService = orderService; //泛型模板构造函数注入使用
_logger = logger;
}
三、两种依赖注入的实例获取方法:
1.默认构造函数注入服务使用,通常是接口服务实例的全部使用;(类似如上泛型模板注册)
2.[FromServices]局部方法注入服务使用,通常指依赖使用某个服务中的一个方法使用;
[HttpGet]
public int GetService([FromServices]IMySingletonService singleton1,
[FromServices]IMySingletonService singleton2,
[FromServices]IMyTransientService transient1,
[FromServices]IMyTransientService transient2,
[FromServices]IMyScopedService scoped1,
[FromServices]IMyScopedService scoped2)
{
Console.WriteLine($"singleton1:{singleton1.GetHashCode()}");
Console.WriteLine($"singleton2:{singleton2.GetHashCode()}");
Console.WriteLine($"transient1:{transient1.GetHashCode()}");
Console.WriteLine($"transient2:{transient2.GetHashCode()}");
Console.WriteLine($"scoped1:{scoped1.GetHashCode()}");
Console.WriteLine($"scoped2:{scoped2.GetHashCode()}");
Console.WriteLine($"========请求结束=======");
return 1;
}
public int GetServiceList([FromServices]IEnumerable<IOrderService> services)
{
foreach (var item in services)
{
Console.WriteLine($"获取到服务实例:{item.ToString()}:{item.GetHashCode()}");
}
return 1;
}
asp.net core 里面的依赖注入,原理介绍见上一篇(ASP.NET Core 2.0系列学习笔记-DI依赖注入):https://blog.csdn.net/ChaITSimpleLove/article/details/79402008