目录
前言
- 当前文章的 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($"日志");
}