目錄
前言
- 當前文章的 SDK 版本爲 .NET Core 3.1 SDK ,使用ASP.NET Coref內置的依賴注入框架。
一、依賴注入組件包
該組件使用了接口實現分離模式。抽象包只包含接口的定義,實現包包含具體的實現,使用時注入具體實現即可,未來我們可以去做任意擴展。
- Microsoft.Extensions.DependencyInjection.Abstractions
- Microsoft.Extensions.DependencyInjection
二、核心類型
- IServiceCollection → ServiceCollection 是負責服務的註冊
- ServiceDescriptor → ServiceDescriptor 是每一個服務註冊時的信息
- IServiceProvider → ServiceProvider 是我們的具體的容器,由ServiceCollection Build 出來的
- IServiceScope → ServiceScope 表示一個容器的子容器的生命週期
三、生命週期和註冊
- 單例 Singleton
- 作用域 Scoped
- 瞬時(暫時)Transient
1) 註冊服務不同生命週期的服務
// 單例
services.AddSingleton<IT, T>();
// 作用域
services.AddScoped<IT, T>();
// 瞬時
services.AddTransient<IT, T>();
2) 花式註冊
// 直接注入實例
services.AddSingleton<IT>(new T());
// 工廠方式註冊(適用於單例、範圍、瞬時)
services.AddSingleton<IT>(provider => {
// provider 可從容器內獲取更多對象,進行組裝
return new T();
});
3)嘗試註冊
嘗試註冊表示如果服務已經註冊過了,就不再註冊
// 服務已經註冊過了,就不再註冊
services.TryAddSingleton<IT, T>();
// 相同類型的服務接口,實現是不同的就可以註冊進去
// 如果實現類是相同的,就不註冊進去
services.TryAddEnumerable(ServiceDescriptor.Singleton<IT, T>());
//services.TryAddEnumerable(ServiceDescriptor.Singleton<IT>(p =>
//{
// return new T();
//}));
4)移動和替換註冊
// Replace 會替換掉我們註冊的第一個實現(基於IT替換)
services.Replace(ServiceDescriptor.Singleton<IT, T>());
// 移除所有基於 IT 註冊
services.RemoveAll<IT>();
5)註冊泛型模板
public interface IService<T> { ... }
public class Service<T> : IService<T> { ... }
// 註冊泛型模板
services.AddSingleton(typeof(IService<>), typeof(Service<>));
四、實例獲取方法
1)使用構造函數注入
大部分接口都需要使用情況下使用構造函數注入
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
public void Get()
{
_logger.LogInformation($"日誌");
}
}
2)將服務直接注入到操作方法
僅僅在某一個接口使用情況下使用 FromServices 注入
[HttpGet]
public void Get([FromServices] ILogger<WeatherForecastController> logger)
{
logger.LogInformation($"日誌");
}