Net6 DI源码分析Part1 ServiceCollectionServiceDescriptorServiceLifetimeIServiceProvider

Posted 一身大膘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Net6 DI源码分析Part1 ServiceCollectionServiceDescriptorServiceLifetimeIServiceProvider相关的知识,希望对你有一定的参考价值。

ServiceCollection、ServiceDescriptor、ServiceLifetime、IServiceProvider

Microsoft.Extensions.DependencyInjection.Abstractions
Microsoft.Extensions.DependencyInjection

基础使用方式
class Car : ICar  
interface ICar  
IServiceCollection services = new ServiceCollection();
ServiceDescriptor transientService = new ServiceDescriptor(typeof(ICar), typeof(Car), ServiceLifetime.Transient);
services.Add(transientService);
services.AddTransient<ICar, Car>();
var serviceProvider = services.BuildServiceProvider();
var car = serviceProvider.GetService(typeof(ICar));
IServiceCollection

存放服务注册的集合

ServiceCollection

它是对IServiceCollection接口的默认实现,
核心属性private readonly List<ServiceDescriptor> _descriptors = new List<ServiceDescriptor>();可以说是对List的一个包装类。

ServiceLifetime

用于描述服务声明周期的枚举 SingletonScopedTransient

ServiceDescriptor

用于描述服务的注册信息
属性,后三个为提供的的服务实际类有关。

  1. ServiceType服务类型
  2. Lifetime生命周期
  3. Type ImplementationType
  4. Func<IServiceProvider,object> ImplementationFactory
  5. object ImplementationInstance

它还提供了一系列静态方法供用于创建ServiceDescriptor

  1. ServiceDescriptor.Transient
    transientService = ServiceDescriptor.Transient(typeof(ICar), typeof(Car));
  2. ServiceDescriptor Describe
    例如ServiceDescriptor.Transient
    transientService = ServiceDescriptor.Describe(typeof(ICar), typeof(Car), ServiceLifetime.Transient);

多数情况下是使用ServiceCollectionServiceExtensionsIServiceCollection扩展的一系列方法添加服务到IServiceCollection集合。

ServiceCollectionServiceExtensions

作为IServiceCollection提供了一系列添加服务注册信息到IServiceCollection集合集合内,内部基本都是创建对应的ServiceDescriptor然后调用IServiceCollection.Add方法添加到集合内。

IServiceProviderFactory

IServiceProvider的工厂接口默认实现为DefaultServiceProviderFactory

DefaultServiceProviderFactory

IServiceProvider的工厂类
构造函数

  1. public DefaultServiceProviderFactory() : this(ServiceProviderOptions.Default)
  2. public DefaultServiceProviderFactory(ServiceProviderOptions options)
    两个方法
  3. public IServiceCollection CreateBuilder(IServiceCollection services)
  4. public IServiceProvider CreateServiceProvider(IServiceCollection containerBuilder) 它的内部CreateServiceProvider也是调用的ServiceCollectionContainerBuilderExtensions提供的扩展方法。
ServiceCollectionContainerBuilderExtensions

对IServiceCollection的扩展作用就是创建IServiceProvider例如提供了BuildServiceProvider

IServiceProvider

仅有的一个方法为用于获取服务。object? GetService(Type serviceType);ServiceProvider是它的默认实现ServiceProvider`

ServiceProviderOptions
  1. ValidateScopes 验证服务之前的Scopes依赖:例如 Singleton 服务依赖另一个Scoped服务,那么这个Scoped服务实例将被一个Singleton服务实例所引用,这时候此Scoped服务实例成了一个Singleton服务实例,如果设置为True ServiceProvider的构造方法内会创建一个CallSiteValidator对象给自己的_callSiteValidator属性。 验证动作会在当Provider获取到CallSiteSerivce后对其进行验证。

  2. ValidateOnBuild IServiceProvider 对象被构建的时候会检验提供的每个ServiceDescriptor 的有效性 例如注册的Car 没有一个可以用的构造函数 class Car : ICar private Car() 的情况 。如果设置为True此时在buildServicePrivate时会抛出异常,否则需要等GetService时才会抛出异常。这是因为这个验证是在CallSiteFactory.GetCallSite动作里面做的,当设置为true是 也只是在ServiceProvider构造函数内调用了ValidateService方法该方法循环调用CallSiteFactory.GetCallSite(ServiceDescriptor serviceDescriptor, CallSiteChain callSiteChain),也就是说把,ServiceCallSite的创建动作提前。注意GetCallSite是个重载方法。具体区别会写在CallSiteFactory章节

文章中提到的代码,请在source.dot.net快速搜索预览


本文来自博客园,作者:一身大膘,转载请注明原文链接:https://www.cnblogs.com/hts92/p/15798238.html

以上是关于Net6 DI源码分析Part1 ServiceCollectionServiceDescriptorServiceLifetimeIServiceProvider的主要内容,如果未能解决你的问题,请参考以下文章

Istio Mixer Cache工作原理与源码分析Part1-基本概念

Spring框架进阶Spring V3.0 DI源码分析流程

TiFlash 源码阅读 DeltaTree 存储引擎设计及实现分析 - Part 2

TiFlash 源码阅读 DeltaTree 存储引擎设计及实现分析 - Part 2

Asp.NET Core 一个接口的多个实现如何通过 DI 注册?

Spring5源码分析(004)——IoC篇之理解Ioc