依赖注入

1.5 依赖注入框架:管理服务的依赖与生命周期.pdf

ASP.NET Core 的依赖注入实现用到了 —— 接口实现分离模式。

  • Microsoft.Extensions.DependencyInjection.Abstractions 抽象包 只包含接口的定义
  • Microsoft.Extensions.DependencyInjection 实现包 包含具体的实现
  • 使用时,组件只需要依赖于它的抽象接口,不需依赖于实现,使用时再注入具体实现
    • 这样的一大好处是方便替换依赖注入框架

核心类型:

  • IServiceCollection:负责服务的注册
  • ServiceDescriptor:每个服务注册时的信息
  • IServiceProvider:具体的容器,由 ServiceCollection Build 出来
  • IServiceScope:表示一个容器的子容器的生命周期

生命周期:

  • 单例 Singleton:在根容器的生命周期内都是单例
  • 作用域 Scoped:在容器(或子容器)的生存周期内,都是一个对象。如果容器释放掉,对象也随之释放
  • 瞬时(暂时) Transient:每一次去容器里面获取对象时,都可以得到一个全新的对象

image.png

两种获取依赖注入实例的方法

  1. 通过 Controller 的构造函数(推荐)
  2. [FromServices](服务仅被单一接口使用时,推荐该方法)
  1. // Controller
  2. public WeatherForecastController(ILogger<WeatherForecastController> logger, IOrderService orderService, IGenericService<IOrderService> genericService)
  3. {
  4. _orderService = orderService;
  5. _logger = logger;
  6. }
  7. // [FromServices]
  8. [HttpGet]
  9. public int GetService([FromServices]IMySingletonService singleton1,
  10. [FromServices]IMySingletonService singleton2,
  11. [FromServices]IMyTransientService transient1,
  12. [FromServices]IMyTransientService transient2,
  13. [FromServices]IMyScopedService scoped1,
  14. [FromServices]IMyScopedService scoped2)
  15. {
  16. Console.WriteLine($"singleton1:{singleton1.GetHashCode()}");
  17. Console.WriteLine($"singleton2:{singleton2.GetHashCode()}");
  18. Console.WriteLine($"transient1:{transient1.GetHashCode()}");
  19. Console.WriteLine($"transient2:{transient2.GetHashCode()}");
  20. Console.WriteLine($"scoped1:{scoped1.GetHashCode()}");
  21. Console.WriteLine($"scoped2:{scoped2.GetHashCode()}");
  22. Console.WriteLine($"========请求结束=======");
  23. return 1;
  24. }