依赖注入
ASP.NET Core 的依赖注入实现用到了 —— 接口实现分离模式。
- Microsoft.Extensions.DependencyInjection.Abstractions 抽象包 只包含接口的定义
- Microsoft.Extensions.DependencyInjection 实现包 包含具体的实现
- 使用时,组件只需要依赖于它的抽象接口,不需依赖于实现,使用时再注入具体实现
- 这样的一大好处是方便替换依赖注入框架
核心类型:
- IServiceCollection:负责服务的注册
- ServiceDescriptor:每个服务注册时的信息
- IServiceProvider:具体的容器,由 ServiceCollection Build 出来
- IServiceScope:表示一个容器的子容器的生命周期
生命周期:
- 单例 Singleton:在根容器的生命周期内都是单例
- 作用域 Scoped:在容器(或子容器)的生存周期内,都是一个对象。如果容器释放掉,对象也随之释放
- 瞬时(暂时) Transient:每一次去容器里面获取对象时,都可以得到一个全新的对象
两种获取依赖注入实例的方法
- 通过 Controller 的构造函数(推荐)
[FromServices]
(服务仅被单一接口使用时,推荐该方法)
// Controller
public WeatherForecastController(ILogger<WeatherForecastController> logger, IOrderService orderService, IGenericService<IOrderService> genericService)
{
_orderService = orderService;
_logger = logger;
}
// [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;
}