一、依賴注入核心組件包:
• 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