IOC
IOC: Inversion of Control 把对象的创建统—交给第三方容器来创见;
DI : 依赖注入
依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。
基础使用IOC
第一种方式
1.如何使用内置IOC
⒉.在需要使用的控制器中,通过构造函数,定义服务的抽象类型,作为参数,在运行时,自动得到服务的具体;
3.调用服务内部的方法
public class TestServiceAController:Controller
{
private readonly ITestServiceA _testServiceA = null;
public TestServiceAController(ITestServiceA itestServiceA)
{
_testServiceA = itestServiceA;
}
public IActionResult Index()
{
//ITestServiceA testServiceA = new TestServiceA();
//testServiceA.show();
_testServiceA.show();
return View();
}
}
第二张方式
1.在Startup中的ConfigureServices方法中注册服务
2.在需要使用的控制器中,通过构造函数,注入lServiceProvider
3.通过_serviceProvider获取到服务,然后通过服务实例调用服务内部的方法
public class TestServiceAController:Controller
{
private readonly ITestServiceA _testServiceA = null;
//IServiceProvider:定义用于检索服务对象的机制;也即,向其他对象提供自定义支持的对象。
private readonly IServiceProvider _serviceProvider1 = null;
public TestServiceAController(ITestServiceA itestServiceA,IServiceProvider serviceProvider)
{
_testServiceA = itestServiceA;
_serviceProvider1 = serviceProvider;
}
public IActionResult Index()
{
ITestServiceA testServiceA =(ITestServiceA) _serviceProvider1.GetService(typeof(ITestServiceA));
testServiceA.show();
return View();
}
}
第三种方式
在注册服务后,视图中通过关键宁@lnject获取实例
@using Services
@inject ITestServiceA itestServiceA //获取到服务实例
@{
itestServiceA.show();
}
DI依赖注入:IServiceCollection支持且仅支持构造函数注入
什么是依赖注入呢?
如粟对象A依赖于对象B,对象B依赖于对象C,就可以先构造对象C,然后传递给对象B,然后把对象B传递给对象A,得到A的具体实例;
可以支持无线层级的以来注入;前提是都要先注入服务(注册抽象和具体的映射关系)
TestServiceB
public class TestServiceB : ITestServiceB
{
public TestServiceB( ITestServiceA itestServiceA)
{
Console.WriteLine($"{this.GetType().Name}被构造");
}
public void show()
{
Console.WriteLine("TestServiceB");
}
}
TestServiceAController
public class TestServiceAController:Controller
{
private readonly ITestServiceA _testServiceA = null;
private readonly ITestServiceB _testServiceB= null;
//IServiceProvider:定义用于检索服务对象的机制;也即,向其他对象提供自定义支持的对象。
private readonly IServiceProvider _serviceProvider1 = null;
public TestServiceAController(ITestServiceA itestServiceA,
IServiceProvider serviceProvider, ITestServiceB itestServiceB)
{
_testServiceA = itestServiceA;
_serviceProvider1 = serviceProvider;
_testServiceB = itestServiceB;
}
public IActionResult Index()
{
_testServiceB.show();
return View();
}
}
IOC生命周期
瞬时生命周期: 每一次getService获得的实例都是不同的实例
单例生命周期: 在整个进程中获取的都是同一个实例
作用域生命周期: 同一个作用域,获取的是同一个实例
建议:开发工作中,一般情况下,都是―起诘求一个对象的实例;更多的是瞬时生命周期的使用;
//瞬时生命周期
{
//IServiceCollection serviceCollection = new ServiceCollection();
//serviceCollection.AddTransient<ITestServiceA, TestServiceA>();//瞬时生命周期,每一次getService获得的实例都是不同的实例
//ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
//ITestServiceA testServiceA = serviceProvider.GetService<ITestServiceA>();
//ITestServiceA testServiceA1 = serviceProvider.GetService<ITestServiceA>();
//bool isOK = object.ReferenceEquals(testServiceA, testServiceA1);//结果为false;两次获取的对象不是同一个实例
}
//单例的生命周期
{
//IServiceCollection serviceCollection = new ServiceCollection();
//serviceCollection.AddSingleton<ITestServiceA, TestServiceA>();//单例生命周期,在整个进程中获取的都是同一个实例
//ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
//ITestServiceA testServiceA = serviceProvider.GetService<ITestServiceA>();
//ITestServiceA testServiceA1 = serviceProvider.GetService<ITestServiceA>();
//bool isOK = object.ReferenceEquals(testServiceA, testServiceA1);//结果为true;两次获取的对象是同一个实例
}
//作用域生命周期
{
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddScoped<ITestServiceA, TestServiceA>();//作用域生命周期,同一个作用域,获取的是同一个实例
ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
ITestServiceA testServiceA = serviceProvider.GetService<ITestServiceA>();
ITestServiceA testServiceA1 = serviceProvider.GetService<ITestServiceA>();
bool isOK = object.ReferenceEquals(testServiceA, testServiceA1);//结果为true;两次获取的对象是同一个实例
ServiceProvider serviceProvider2 = serviceCollection.BuildServiceProvider();
ITestServiceA testServiceA2 = serviceProvider2.GetService<ITestServiceA>();
bool isOK2 = object.ReferenceEquals(testServiceA1, testServiceA2);//结果为false;两次获取的对象是同一个实例
}