提到依赖不得不提到,控制反转(Inversion of Control,IOC)这个概念,简单的来讲就是将控制对象的权限交给框架,不再手动完成。IOC实现方式有2种:
1、服务定位器(ServiceLocator),主动获取对象
2、依赖注入(Dependency Injection,DI),在使用的地方申明对象,由框架自动赋值。
DI好处:简化模块的组装过程,降低模块之间的耦合度。
---------------------------------------------------------------------------------------------------------------------------------DI常见概念:
1、服务(Service):对象;
2、注册服务;
3、服务容器:负责管理注册的服务
4、查询服务:创建对象及关联对象
---------------------------------------------------------------------------------------------------------------------------------根据类型获取和注册服务,需要分别指定服务类型(service type)和实现类型(implementation type),服务类型推荐用接口(可以是接口、类),实现类型只能用类。
.Net 控制反转组件取名为:DependecyInjection,也包含ServiceLocator功能
public inteface iTest{
}
public class Test:iTest{
}
---------------------------------------------------------------------------------------------------------------------------------【怎么使用】
1、Nuget 安装 Microsoft.Extensions.DependencyInjection
2、using Microsoft.Extensions.DependencyInjection
cs
ServiceCollection services = new ServiceCollection();//定义一个承放服务的集合
services.AddTransient<GetRole>();//添加一个瞬态的服务
using (ServiceProvider serviceProvider = services.BuildServiceProvider())
{//ServiceProvider 相当于服务定位器
GetRole service = serviceProvider.GetService<GetRole>();
service.Name = "test";
service.GetName();
}
对象生命周期:Transient(瞬态);Scoped(范围)、Singleton(单例)
1、Transient,添加一个瞬态的服务, 每次申明服务时,会创建新的对象。
cs
ServiceCollection services = new ServiceCollection();//定义一个承放服务的集合
services.AddTransient<GetRole>();//添加一个瞬态的服务 每次申明服务时,会创建新的对象
using (ServiceProvider serviceProvider = services.BuildServiceProvider())
{
GetRole service = serviceProvider.GetService<GetRole>();
service.Name = "test";
service.GetName();
GetRole service1 = serviceProvider.GetService<GetRole>();
service1.Name = "test2";
service1.GetName();
//结果:service!=service1
}
2、Singleton,添加一个单例的服务 每次申明服务时,会指向同一对象。
3、Scope,添加一个范围的服务 范围内的申明的服务,会指向同一对象
注:如果申明的Singleton,在Scope范围申明的服务视为Singleton的情况。
cs
ServiceCollection services = new ServiceCollection();//定义一个承放服务的集合
services.AddScoped<GetRole>();
using (ServiceProvider serviceProvider = services.BuildServiceProvider())
{
//Scope用法
using (IServiceScope scope1 = serviceProvider.CreateScope())
{
GetRole service = scope1.ServiceProvider.GetService<GetRole>();
service.Name = "test";
service.GetName();
GetRole service2 = scope1.ServiceProvider.GetService<GetRole>();
service1.Name = "test";
service1.GetName();
//范围内service=service2
}
using (IServiceScope scope2 = serviceProvider.CreateScope())
{
GetRole service3 = scope2.ServiceProvider.GetService<GetRole>();
service.Name = "test";
service.GetName();
GetRole service4 = scope2.ServiceProvider.GetService<GetRole>();
service1.Name = "test";
service1.GetName();
}
//范围外service2!=service3
其他知识点:Dispose 释放资源
如果服务继承了IDisposable接口,在离开Scope范围时,会自动调用类的Dispose方法释放资源。