引言
控制反转(IoC)实现方法:
- (隐式)依赖注入:需要什么服务(类),直接在类里面写,然后系统在创建类的时候给服务(类)自动赋值。
- (显式)服务定位器:需要什么服务(类)在给服务定位器要什么服务(类)
1. 初始化使用
引用包:Microsoft.Extensions.DependencyInjection
首先需要创建一个容器:ServiceCollection
然后在容器中注册服务(类)
然后用ServiceProvider
获取注册的对象
实例代码:
public interface ITestService
{
public string Name { get; set; }
public void SayHi();
}
public class TestServiceImpl : ITestService
{
public string Name { get; set; }
public void SayHi()
{
Console.WriteLine($"Hi , I'm {Name}");
}
}
public class TestServiceImpl2 : ITestService
{
public string Name { get; set; }
public void SayHi()
{
Console.WriteLine($"你好 我是 {Name}");
}
}
// 容器对象
ServiceCollection services = new ServiceCollection();
// 注册服务
services.AddTransient<TestServiceImpl>();
// 获取注册服务需要用到的工具
using(ServiceProvider serviceProvider = services.BuildServiceProvider())
{
// 获取注册的服务
TestServiceImpl test = serviceProvider.GetService<TestServiceImpl>();
test.Name = "zz";
test.SayHi();
}
2. 服务使用范围
服务范围分为三种:
- 单例:整个容器使用同一个实例对象
- 瞬态:每次获取的都是一个新的实例对象
- 范围:在一个范围内获取的是同一个实例对象
ServiceCollection services = new ServiceCollection();
//services.AddSingleton<TestServiceImpl>();// 创建单例
services.AddTransient<TestServiceImpl>();// 创建瞬态
//services.AddScoped<TestServiceImpl>();// 创建范围
using (ServiceProvider sp = services.BuildServiceProvider())
{
TestServiceImpl t1 = sp.GetService<TestServiceImpl>();
TestServiceImpl t2 = sp.GetService<TestServiceImpl>();
TestServiceImpl t3 = null;
// 创建一个范围
using (IServiceScope scope = sp.CreateScope())
{
// 在范围中使用Provider
t1 = scope.ServiceProvider.GetService<TestServiceImpl>();
t1.Name = "aa";
t3 = scope.ServiceProvider.GetService<TestServiceImpl>();
t3.Name = "dd";
}
// 创建一个新的范围
using(IServiceScope scope = sp.CreateScope())
{
t2 = scope.ServiceProvider.GetService<TestServiceImpl>();
t2.Name = "bb";
}
// 单例情况 t1=t2 && t1==t3
Console.WriteLine(t1==t2 && t1==t3);
// 瞬态情况 t1!=t2 && t1 != t3
Console.WriteLine(t1!=t2 && t1 != t3);
// 范围情况 t1!=t2 && t1 == t3
Console.WriteLine(t1!=t2 && t1==t3);
t1.SayHi();
t2.SayHi();
t3.SayHi();
}
注册方法和获取实例的方法
ServiceCollection services = new ServiceCollection();
// 注册类与实现类相同
services.AddTransient<TestServiceImpl>();
// 注册类与实现类不同
//services.AddTransient<ITestService,TestServiceImpl>();
// 注册的不同方式,与上面的注册方式结果一致
services.AddTransient(typeof(ITestService),typeof(TestServiceImpl));
// 相同的注册类有多个不同的实现类
services.AddTransient(typeof(ITestService), typeof(TestServiceImpl2));
using (ServiceProvider sp = services.BuildServiceProvider())
{
// 如果要获取的注册类不存在GetService则返回null
TestServiceImpl2 te2 = sp.GetService<TestServiceImpl2>();
Console.WriteLine(te2);
// 如果要获取的注册类不存在GetRequiredService则提示错误
TestServiceImpl2 te3 = sp.GetRequiredService<TestServiceImpl2>();
Console.WriteLine(te3);
// 使用注册类获取想要的类
TestServiceImpl t1 = sp.GetService<TestServiceImpl>();
// 使用注册类获取想要的类
//ITestService t2 = sp.GetService<ITestService>();
// 不使用泛型获取对象 需要手动转换类型 与上面结果一致
ITestService t2 = (ITestService)sp.GetService(typeof(ITestService));
t1.Name = "aa";
t1.SayHi();
t2.Name = "bb";
t2.SayHi();
// 注册多个不同的实现类,如果使用GetService则获取最后注册的实现类
ITestService t3 = sp.GetService<ITestService>();
t3.Name = "cc";
t3.SayHi();
// 获取多个不同的实现类用GetServices
IEnumerable<ITestService> t4 = sp.GetServices<ITestService>();
foreach (ITestService t in t4)
{
t.Name = "11";
t.SayHi();
}
}
标签:Name,DI,t2,t3,t1,services,net,GetService,IoC
From: https://www.cnblogs.com/sunhouzi/p/17859733.html