Net6 DI原始碼分析Part2 Engine,ServiceProvider

一身大膘發表於2022-02-09
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)。其 SingletonScoped型別的生命週期相同。

  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. 初始化預設的 _createServiceAccessorCreateServiceAccessor
    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實現了此介面

相關文章