Net6 DI原始碼分析Part1 ServiceCollection、ServiceDescriptor、ServiceLifetime、IServiceProvider

一身大膘發表於2022-02-10
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章節

相關文章