控制反转(Inversion of Control - IoC)
、IoC 是一种设计原则,也是一种设计思想
、IoC 是将对象的控制权从代码本身转移到容器中,由容器负责对象的创建、管理以及依赖关系的注入
、IoC 主要目的是降低了代码间的耦合度,提高了系统的灵活性和可维护性
、IoC 可以更加灵活的管理对象及其依赖关系,而无需显式地创建和管理对象
、开发者能够更专注于业务逻辑的实现,不用花费大量时间在对象的管理和依赖关系的处理上
、IoC 容器是一个专门用于管理对象生命周期和依赖关系的组件
、IoC 容器可以根据配置文件或注解等方式来创建和注入对象及其依赖关系
、2种实现方式:服务定位器(ServiceLoctor)、依赖注入(DI)
两者的区别是:ServiceLoctor 是通过应用程序实现, DI 是通过框架自动实现
服务定位器(ServiceLoctor)
、将所需对象注册到容器中
、直接从容器中获取对象
依赖注入(Dependency Injection - DI)
、DI 是 IoC 的一种具体实现方式
、DI 是依赖倒置原则的实践,依赖倒置原则:是要求对抽象进行编程,不要对实现进行编程
、DI 是某个对象需要调用另一个对象时,不是由调用者自己创建被调用者的实例,而是由外部容器或框架来创建并注入这个依赖对象
、DI 降低了代码间的耦合度,提高了系统的灵活性和可维护性
、3种实现方式:构造函数注入(.NET 默认)、属性注入、接口注入
DI 相关概念
、服务:对象
、注册服务:把服务添加到容器中
、服务容器:管理服务的注册与解析
、查询服务:创建对象、创建关联对象
、服务生命周期:通过 DI 创建的服务,有三种生命周期
– Transient(瞬态):每次请求都创建一个新对象
– Scoped(范围):在给定范围内,多次请求共享一个对象,一次 Http 请求,就是一个范围
– Singleton(单例):每次请求都是同一个对象
控制台项目实现步骤:
、安装 NuGet 包:Microsoft.Extensions.DependencyInjection
、创建服务容器,例:ServiceCollection services = new ServiceCollection();
、注册服务,例:services.AddScoped<ITestService, TestService>();
– 注册服务可以分别指定服务类型和实现类型,两者可以相同,也可以不同
– 服务类型可以是接口,也可以是类,建议面向接口编程,更灵活
、创建服务定位器,例:using ServiceProvider sp = services.BuildServiceProvider();
、获取服务,例: ITestService testService = sp.GetService();
– 获取服务的三种方式:构造函数注入、方法参数注入([FromServices]ITestService testService)、服务定位器
– 服务中一般使用构造函数注入,MiniApi 中一般使用服务定位器
、调用服务方法
应用程序项目实现步骤:
、.NET 提供了一个内置的 DI 容器
、.NET5 在 Startup 类的 ConfigureServices 方法中,通过参数 IServiceCollection 注册服务,例:service.AddScoped<ITestService, TestService>();
、.NET6 在 Program 类中,通过 builder 注册服务,例:builder.Services.AddScoped<ITestService, TestService>();
、在需要使用服务的类中,通过构造函数注入方式获取服务
说明:
、DI 具有传染性,如果一个类的对象是通过 DI 创建的,那么这个类的构造函数中声明的所有服务类型的参数都会被 DI 创建
、生命周期选择:如果类无状态,建议为 Singleton;如果类有状态,且有 Scope 控制,建议为 Scoped;使用 Transient 需要谨慎
、不要在长生命周期的对象中引用比它生命周期短的对象
、如果一个类实现了 IDisposable 接口,则离开作用域之后容器会自动调用对象的 Dispose 方法