DI容器本质上是一个工厂,负责提供向它请求的类型的实例。
.net core内置了一个轻量级的DI容器,方便开发人员面向接口编程和依赖倒置(IOC)。
具体体现为Micorosoft.Extensions.DependencyInjection这个包。
.net core中内置的DI容器包含两大要素:ServiceCollection和ServiceProvider。
为了便于理解,我画了一张图:
通过上面的UML类图可以看出ServiceCollection其实就是一个集合,存放接口和实现的对应关系。这个集合的Item就是ServiceDescriptor类。ServiceDescriptor类有两个类型为Type的属性。一个代表接口类型,一个代表实现类的类型,形成对应关系。
ServicePorvider可以理解为具体服务的提供器。它是由ServiceCollection的扩展方法BuildServiceProvider创建的。我们需要什么服务,从提供器取就行了。通过上图可以看到ServicePorvider有个方法叫:GetService,这个方法会根据我们提供的接口从ServiceDescriptor集合中(ServiceCollection)中查找对应的实现类。当ServiceType和传入的接口类型一致后,再从匹配的ServiceDescriptor拿到ImplementationType实现类型,最后实例化该类型返回给我们。
上面获取实现类的描述,没有考虑ImplementationInstance和ImplementationFactory。更高大上的还是看大神的博客吧。
以下面的代码为例:
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
我们知道ILogger<T>已经默认被注入到DI容器了。当程序创建HomeController类时,首先会通过构造方法检测到它依赖Ilogger<HomeController>接口,这个时候我们的DI容器就会查找与这个接口对应的实现类,并自动创建这个实现类的实例。