在AspNetCore中会默认地配备一个依赖注入框架,该框架有下面两个组件包:
- Microsoft.Extensions.DependencyInjection.Abstractions
- Microsoft.Extensions.DependencyInjection
一个是抽象包,另一个是实现包
依赖注入框架有以下四个核心类型:
- IServiceCollection:负责服务的注册
- ServiceDescriptor:每一个服务注册时的信息
- IServiceProvider:注册时注入服务的容器,由ServiceCollection的Build方法构建出来
- IServiceScope:表示一个容器的子容器的生命周期
生命周期:ServiceLifetime
- 单例:Singleton,指在整个跟容器的生命周期内,都是同一个实例,即作用域是全局的。
- 作用域:Scoped,指在Scope的生存周期内,也就是容器的生存周期内,或者子容器的生存周期内,若容器释放掉,实例也会被释放掉,即作用域是局部的。
- 瞬时:Transient,指每一次去从容器中获取对象时,都可以得到一个新的实例。
注册服务的方式:
- 花式注册
1
2
3
4
5
6
7
8
9
10/*
services.AddSingleton<接口>(实现接口的类);//单例模式
services.AddScoped<接口>(实现接口的类);//作用域模式
services.AddTransient<接口>(实现接口的类);//瞬时模式
services.AddSingleton<接口,实现接口的类>();//单例模式
services.AddScoped<接口,实现接口的类>();//作用域模式
services.AddTransient<接口,实现接口的类>();//瞬时模式
*/
services.AddSingleton<IOrderService>(new OrderService());
services.AddSingleton<IOrderService, OrderService>();- 使用工厂方式来注册
1
2
3
4
5services.AddSingleton<IOrderService>(service =>
{
var logger = service.GetService<ILogger>();
return new OrderService();
});使用工厂方式来注册可以对实例来进行一系列的操作,比如用其他的组件来组装新的实例,即实现依赖了容器内另外一个实现
- 使用TryAdd方式来注册
1
2
3
4
5
6
7
8
9
10/*
TryAddxxx表示尝试注册,即若服务已经被注册了,这该语句不会被执行,否则被执行
*/
services.TryAddSingleton<IOrderService, OrderService>();
services.TryAddScoped<IOrderService, OrderService>();
services.TryAddTransient<IOrderService, OrderService>();
/*
TryAddEnumerable和上面的三种注册方法有一些区别,表示的是如果服务的实现类已经被注册了,则该方法不被执行,否则被执行,即可以用该方法注册同一个服务的不同实现类
*/
services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>());- 使用Replace来替换服务,使用RemoveAll来移除服务
1
2
3
4
5
6
7/*
使用Replace来将IOrderService服务中的OrderService替换成OrderServiceEx
使用RemoveAll来将所有的实现IOrderService的实现从容器中移除
*/
services.AddSingleton<IOrderService, OrderService>();
services.Replace(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>());
services.RemoveAll<IOrderService>();- 泛型模板的注册
1
2
3services.AddSingleton(typeof(IGenericService<>), typeof(GenericService<>));
//使用时,可以在<>放容器中的组件,即IGenericService依赖了IOrderService
IGenericService<IOrderService>
获取服务实例的方法
- 在构造函数中注入服务,一般用于服务适用于整个类
- 使用[FromService]特性注册服务,一般用于服务适用于类的某个方法或属性等