为什么要使用依赖注入框架

  • 依赖注入框架其实也就是我们通常所说的IOC框架,这个框架可以帮助我们来管理类与类之间的依赖关系。
  • 借助依赖注入框架,我们可以轻松管理类之间的依赖,帮助我们在构建应用时遵循设计原则,确保代码的可维护性和可扩展性。
  • ASP.NET Core的整个架构中,依赖注入框架提供了对象创建和生命周期管理的核心能力,各个组件相互协作,也是由依赖注入框架的能力来实现的。

核心组件包

  • 用了一个经典的设计模式,叫做接口实现分离模式
  • Microsoft.Extensions.DependencyInjection.Abstracions (抽象包)
  • Microsoft.Extensions.DependencyInjection (具体实现)

依赖注入框架的核心类型

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

生命周期:ServiceLifetime

  • 单例 Singleton
    • 在整个根容器的生命周期内都是单例,不论根容器还是子容器,与作用域的区别就是一个是全局的,一个是范围的。
  • 作用域 Scoped
    • 在我的Scope的生存周期内也就是容器的生存周期内,或者子容器的生存周期内,如果我的容器释放掉,那就意味着我的对象也会释放掉。在这个范围内的话,我们得到是一个单例模式。
  • 瞬时(暂时) Transient
    • 每一次去从容器里面获取对象时,都可以得到一个全新的对象

首先我们新建Web程序👉选择API模板

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. #region 注册服务不同的生命周期
  4. // 单例
  5. services.AddSingleton<IMySingletonService, MySingletonService>();
  6. // 作用域
  7. services.AddScoped<IMyScopedService, MyScopedService>();
  8. // 瞬时
  9. services.AddTransient<IMyTransientService, MyTransientService>();
  10. #endregion
  11. #region 花式注册
  12. // 自己创建对象
  13. services.AddSingleton<IOrderService>(new OrderService());
  14. // 工厂
  15. services.AddSingleton<IOrderService>(serviceProvider =>
  16. {
  17. return new OrderService();
  18. });
  19. services.AddSingleton<IOrderService>(serviceProvider =>
  20. {
  21. return new OrderService();
  22. });
  23. #endregion
  24. #region 尝试注册
  25. //如果发现已经注册过了就不注册
  26. services.TryAddSingleton<IOrderService, OrderService>();
  27. //将不同实现的实例注册进去
  28. services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>());
  29. #endregion
  30. #region 移除和替换注册
  31. services.RemoveAll<IOrderService>();
  32. services.Replace(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>());
  33. #endregion
  34. #region 注册泛型模板
  35. services.AddSingleton(typeof(IGenericService<>),typeof(GenericService<>));
  36. #endregion
  37. services.AddControllers();
  38. }
  1. // 两种获取到实例的方式
  2. // 1.通过构造函数的方式
  3. public WeatherForecastController(ILogger<WeatherForecastController> logger,IOrderService orderService,IGenericService<OrderService> genericService)
  4. {
  5. _logger = logger;
  6. }
  7. // 2.通过[FormServices]
  8. public int GetServiceList([FromServices]IEnumerable<IOrderService> services)
  9. {
  10. foreach (var item in services)
  11. {
  12. Console.WriteLine($"获取到服务实例:{item}:{item.GetHashCode()}");
  13. }
  14. return 1;
  15. }
  16. // 这两种方式的使用场景时不同的,当我们定义个Conllection的时候,它的服务时大部分接口都需要使用的情况下,
  17. // 推荐的做法时用构造函数的注入方式。
  18. // 如果说时我们这个服务仅仅是在某一个接口使用的情况下,
  19. // 推荐使用[FromServices]的方式来注入。