为什么要使用依赖注入框架
- 依赖注入框架其实也就是我们通常所说的IOC框架,这个框架可以帮助我们来管理类与类之间的依赖关系。
- 借助依赖注入框架,我们可以轻松管理类之间的依赖,帮助我们在构建应用时遵循设计原则,确保代码的可维护性和可扩展性。
- ASP.NET Core的整个架构中,依赖注入框架提供了对象创建和生命周期管理的核心能力,各个组件相互协作,也是由依赖注入框架的能力来实现的。
核心组件包
- 用了一个经典的设计模式,叫做接口实现分离模式
- Microsoft.Extensions.DependencyInjection.Abstracions (抽象包)
- Microsoft.Extensions.DependencyInjection (具体实现)
依赖注入框架的核心类型
- IServiceCollection
- 负责服务的注册
- ServiceDescriptor
- 每一个服务注册时的信息
- IServiceProvide
- 具体的容器也是由ServiceCollection Build出来的
- IServiceScope
- 表示一个容器的子容器的生命周期
生命周期:ServiceLifetime
- 单例
Singleton- 在整个根容器的生命周期内都是单例,不论根容器还是子容器,与作用域的区别就是一个是全局的,一个是范围的。
- 作用域
Scoped- 在我的Scope的生存周期内也就是容器的生存周期内,或者子容器的生存周期内,如果我的容器释放掉,那就意味着我的对象也会释放掉。在这个范围内的话,我们得到是一个单例模式。
- 瞬时(暂时)
Transient- 每一次去从容器里面获取对象时,都可以得到一个全新的对象
首先我们新建Web程序👉选择API模板
public void ConfigureServices(IServiceCollection services){#region 注册服务不同的生命周期// 单例services.AddSingleton<IMySingletonService, MySingletonService>();// 作用域services.AddScoped<IMyScopedService, MyScopedService>();// 瞬时services.AddTransient<IMyTransientService, MyTransientService>();#endregion#region 花式注册// 自己创建对象services.AddSingleton<IOrderService>(new OrderService());// 工厂services.AddSingleton<IOrderService>(serviceProvider =>{return new OrderService();});services.AddSingleton<IOrderService>(serviceProvider =>{return new OrderService();});#endregion#region 尝试注册//如果发现已经注册过了就不注册services.TryAddSingleton<IOrderService, OrderService>();//将不同实现的实例注册进去services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>());#endregion#region 移除和替换注册services.RemoveAll<IOrderService>();services.Replace(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>());#endregion#region 注册泛型模板services.AddSingleton(typeof(IGenericService<>),typeof(GenericService<>));#endregionservices.AddControllers();}
// 两种获取到实例的方式// 1.通过构造函数的方式public WeatherForecastController(ILogger<WeatherForecastController> logger,IOrderService orderService,IGenericService<OrderService> genericService){_logger = logger;}// 2.通过[FormServices]public int GetServiceList([FromServices]IEnumerable<IOrderService> services){foreach (var item in services){Console.WriteLine($"获取到服务实例:{item}:{item.GetHashCode()}");}return 1;}// 这两种方式的使用场景时不同的,当我们定义个Conllection的时候,它的服务时大部分接口都需要使用的情况下,// 推荐的做法时用构造函数的注入方式。// 如果说时我们这个服务仅仅是在某一个接口使用的情况下,// 推荐使用[FromServices]的方式来注入。
