Net6 DI源碼分析Part2 Engine,ServiceProvider

ServiceProvider

ServiceProvider是對IServiceProvider實現,它有一個internal的訪問修飾符描述的構造,並需要兩個參數IServiceCollection & ServiceProviderOptions。所以可以通過 ServiceCollectionContainerBuilderExtensions提供的擴展方法和DefaultServiceProviderFactory工廠類創建實例。
屬性

  1. Func<Type, Func<ServiceProviderEngineScope, object>> _createServiceAccessor
  2. ServiceProviderEngine _engine;
  3. ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>> _realizedServices;
  4. CallSiteFactory CallSiteFactory { get; }
  5. ServiceProviderEngineScope Root { get; }
  6. CallSiteValidator _callSiteValidator;默認"創建服務存取器"的「工廠方法」

方法

  1. void Dispose()
    很簡單,做了一個事情,調用root的對應Dispose。清理根容器構造出來的對象

  2. void OnCreate(ServiceCallSite callSite)
    此方法被用於每次通過CallSiteFactory創建出來的callsite進行驗證然後使用_callSiteValidator去驗證callsite。

  3. object GetService(Type serviceType)
    很簡單,調用同名方法,把root作為serviceProviderEngineScope傳入。也就是你直接build出來的provider獲取的服務均是root提供(廢話)也經常被成為root provider(根容器的provider)。其 Singleton、Scoped類型的生命周期相同。

  4. internal GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
    很簡單,根據type去realizedService如果有值拿對應的「創建服務存取器」否則創建一個默認的,也就是構造函數中初始化的 然後執行委託,把對應的serviceProviderEngineScope傳入。
    存取器內部會有對應的engine。並把傳入參數給engine。engine內部回把創建好的對象放入這個serviceProviderEngineScope內。

         Func<ServiceProviderEngineScope, object> realizedService = _realizedServices.GetOrAdd(serviceType, _createServiceAccessor);
         OnResolve(serviceType, serviceProviderEngineScope);
         var result = realizedService.Invoke(serviceProviderEngineScope);
         return result;
    
  5. Func<ServiceProviderEngineScope, object> CreateServiceAccessor(Type serviceType)
    作為默認的「創建服務存取器」工廠方法做了如下事情

    1. 通過CallSiteFactory獲取對應的ServiceCallSite,並傳入CallSiteChain。CallSiteChain防止循環依賴項
    2. 得到ServiceCallSite後調用OnCreate驗證ServiceCallSite合規性。
    3. 如果是CallSiteResultCacheLocation.Root單例的,固定通過CallSiteRuntimeResolver(RuntimeServiceProviderEngine引擎的符類)產出物委託。算是對「單例」的優化。
    4. 其它生命周期通過_engine的RealizeService產出物委託。
     ServiceCallSite callSite = CallSiteFactory.GetCallSite(serviceType, new CallSiteChain());
     OnCreate(callSite);
     if (callSite.Cache.Location == CallSiteResultCacheLocation.Root)
     {
         object value = CallSiteRuntimeResolver.Instance.Resolve(callSite, Root);
         return scope => value;
     }
     return _engine.RealizeService(callSite);
    
  6. IServiceScope CreateScope();
    ServiceProvider作為所以ServiceProviderEngineScope的父節點
    return new ServiceProviderEngineScope(this, isRootScope: false);

    就算new 了一個新的ServiceProviderEngineScope其內部還是調用this指向的當前serviceProvider的CreateScope去創建對象.

  7. ServiceProviderEngine GetEngine()
    如何選擇引擎,如果是NETFRAMEWORK ,NETSTANDARD2_0 並且支援DynamicCodeCompiled使用DynamicServiceProviderEngine引擎,否則使用RuntimeServiceProviderEngine

    1. DynamicServiceProviderEngine:DynamicServiceProviderEngine的特性是如果同一個類型同一時刻需要創建多次,那麼它會使用ILEmitResolverBuilder/ExpressionResolverBuilder
    2. RuntimeServiceProviderEngineRuntimeServiceProviderEngine內部調用CallSiteRuntimeResolver創建對象 此class 是應用使用反射創建。
    ServiceProviderEngine engine;
    #if NETFRAMEWORK || NETSTANDARD2_0
         engine = new DynamicServiceProviderEngine(this);
     #else
         if (RuntimeFeature.IsDynamicCodeCompiled)
         {
             engine = new DynamicServiceProviderEngine(this);
         }
         else
         {
             // Don't try to compile Expressions/IL if they are going to get interpreted
             engine = RuntimeServiceProviderEngine.Instance;
         }
     #endif
     return engine;
    
  8. 構造方法

    1. 初始化Root
    2. GetEngine 構造服務引擎。
    3. 初始化默認的 _createServiceAccessor 為CreateServiceAccessor。
    4. _realizedServices為每個服務快取一個create Service Accessor(Func<ServiceProviderEngineScope, object>) 以Type作為key,默認為_createServiceAccessor 也就是CreateServiceAccessor。
    5. 提供內部服務註冊資訊
    6. 根據ServiceProviderOptions Options 初始化驗證
    Root = new ServiceProviderEngineScope(this, isRootScope: true);
    _engine = GetEngine();
    _createServiceAccessor = CreateServiceAccessor;
    _realizedServices = new ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>>();
    CallSiteFactory = new CallSiteFactory(serviceDescriptors);
    CallSiteFactory.Add(typeof(IServiceProvider), new ServiceProviderCallSite());
    CallSiteFactory.Add(typeof(IServiceScopeFactory), new ConstantCallSite(typeof(IServiceScopeFactory), Root));
    CallSiteFactory.Add(typeof(IServiceProviderIsService), new ConstantCallSite(typeof(IServiceProviderIsService), CallSiteFactory));
    if (options.ValidateScopes)
    {
        _callSiteValidator = new CallSiteValidator();
    }
    if (options.ValidateOnBuild)
    {
        foreach (ServiceDescriptor serviceDescriptor in serviceDescriptors)
        {
                ValidateService(serviceDescriptor);
        }
    }
    

這裡ServiceProivder的功能很明確單一職責,提供服務,創建Scope,提供引擎,即使ServiceProviderEngineScope也有同名方法,但最終都依賴於ServiceProivder。它們僅僅是包裝了以下。

ServiceProviderEngineScope

它實現了IServiceScope IServiceProvider IServiceScopeFactory所以它可以獲取服務,也可以創建Scope。
屬性。

  1. private List<object> _disposables;
  2. bool IsRootScope
  3. internal ServiceProvider RootProvider
  4. internal Dictionary<ServiceCacheKey, object> ResolvedServices { get; }
    方法。
  5. object GetService(Type serviceType)
  6. IServiceScope CreateScope() => RootProvider.CreateScope();
    CreateScope總是調用RootProvider的同名方法也就是說每一個新的ServiceProviderEngineScope它們的父節點都是同一個。也就是ServieProvider。ServiceProvider作為所以ServiceProviderEngineScope的父節點
  7. void Dispose()
ServiceProviderEngine

一抽象類唯一的方法為RealizeService 主要這裡它僅僅返回的是一個委託,此委託的具體執行由ServiceProvider 的GetService執行
public abstract Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite);

DynamicServiceProviderEngine

該類繼承了CompiledServiceProviderEngine.並重寫了父類的RealizeService,其內部還是通過CallSiteRuntimeResolver服務類去創建服務,但如果統一時刻某一類型被創建多次時,它會做出替換掉該類型的「創建服務存取器」為 base.RealizeService(callSite)也就是CompiledServiceProviderEngine.RealizeService
可以說DynamicServiceProviderEngine職責是根據某一個Type的使用頻率給出個對應類型的「創建服務存取器」 ,不同的「創建服務存取器」 內使用了不同的引擎。

CompiledServiceProviderEngine

CompiledServiceProviderEngine是對ServiceProviderEngine的實現之一

一個屬性ResolverBuilder和一個RealizeService方法
ResolverBuilder 它通過環境去構造出具體的屬性ILEmitResolverBuilder/ExpressionResolverBuilder調用RealizeService方法是僅返回對應ResolverBuilder的產出物的委託。GetService

  internal abstract class CompiledServiceProviderEngine : ServiceProviderEngine
    {
#if IL_EMIT
        public ILEmitResolverBuilder ResolverBuilder { get; }
#else
        public ExpressionResolverBuilder ResolverBuilder { get; }
#endif
 
        public CompiledServiceProviderEngine(ServiceProvider provider)
        {
            ResolverBuilder = new(provider);
        }
 
        public override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite) => ResolverBuilder.Build(callSite);
    }
RuntimeServiceProviderEngine

同樣也是對抽象類ServiceProviderEngine的實現,重寫抽象方法後,它內部直接返回CallSiteRuntimeResolver的Resolve方法的產出物的委託。

        public override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite)
        {
            return scope =>
            {
                return CallSiteRuntimeResolver.Instance.Resolve(callSite, scope);
            };
        }

>ServiceProviderEngine.Resolve總結

Engine的Resolve方法返回的均是委託最終在serviceProivder的GetService中執行,得到實例對象也就是我們的最終交給使用者的服務。engine創建對象依賴的均是ServiceCallSite它是由CallSiteFactory根據Type創建的。

IServiceScopeFactory

唯一一個方法IServiceScope CreateScope();,ServiceProviderEngineScope實現了此介面

IServiceScope: IDisposable

唯一一個屬性IServiceProvider ServiceProvider { get; },ServiceProviderEngineScope實現了此介面

Tags: