Net6 DI源碼分析Part2 Engine,ServiceProvider
ServiceProvider
ServiceProvider是對IServiceProvider實現,它有一個internal的訪問修飾符描述的構造,並需要兩個參數IServiceCollection & ServiceProviderOptions。所以可以通過 ServiceCollectionContainerBuilderExtensions提供的擴展方法和DefaultServiceProviderFactory工廠類創建實例。
屬性
Func<Type, Func<ServiceProviderEngineScope, object>> _createServiceAccessorServiceProviderEngine _engine;ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>> _realizedServices;CallSiteFactory CallSiteFactory { get; }ServiceProviderEngineScope Root { get; }CallSiteValidator _callSiteValidator;默認"創建服務存取器"的「工廠方法」
方法
-
void Dispose()
很簡單,做了一個事情,調用root的對應Dispose。清理根容器構造出來的對象 -
void OnCreate(ServiceCallSite callSite)
此方法被用於每次通過CallSiteFactory創建出來的callsite進行驗證然後使用_callSiteValidator去驗證callsite。 -
object GetService(Type serviceType)
很簡單,調用同名方法,把root作為serviceProviderEngineScope傳入。也就是你直接build出來的provider獲取的服務均是root提供(廢話)也經常被成為root provider(根容器的provider)。其Singleton、Scoped類型的生命周期相同。 -
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; -
Func<ServiceProviderEngineScope, object> CreateServiceAccessor(Type serviceType)
作為默認的「創建服務存取器」工廠方法做了如下事情- 通過CallSiteFactory獲取對應的ServiceCallSite,並傳入CallSiteChain。
CallSiteChain防止循環依賴項 - 得到ServiceCallSite後調用OnCreate驗證ServiceCallSite合規性。
- 如果是CallSiteResultCacheLocation.Root單例的,固定通過
CallSiteRuntimeResolver(RuntimeServiceProviderEngine引擎的符類)產出物委託。算是對「單例」的優化。 - 其它生命周期通過_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); - 通過CallSiteFactory獲取對應的ServiceCallSite,並傳入CallSiteChain。
-
IServiceScope CreateScope();
ServiceProvider作為所以ServiceProviderEngineScope的父節點
return new ServiceProviderEngineScope(this, isRootScope: false);就算new 了一個新的ServiceProviderEngineScope其內部還是調用this指向的當前serviceProvider的CreateScope去創建對象.
-
ServiceProviderEngine GetEngine()
如何選擇引擎,如果是NETFRAMEWORK ,NETSTANDARD2_0 並且支援DynamicCodeCompiled使用DynamicServiceProviderEngine引擎,否則使用RuntimeServiceProviderEngine- DynamicServiceProviderEngine:DynamicServiceProviderEngine的特性是如果同一個類型同一時刻需要創建多次,那麼它會使用ILEmitResolverBuilder/ExpressionResolverBuilder
- 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; -
構造方法
- 初始化
Root GetEngine構造服務引擎。- 初始化默認的
_createServiceAccessor為CreateServiceAccessor。 - _realizedServices為每個服務快取一個create Service Accessor(
Func<ServiceProviderEngineScope, object>) 以Type作為key,默認為_createServiceAccessor也就是CreateServiceAccessor。 - 提供內部服務註冊資訊
- 根據
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。
屬性。
private List<object> _disposables;bool IsRootScopeinternal ServiceProvider RootProviderinternal Dictionary<ServiceCacheKey, object> ResolvedServices { get; }
方法。object GetService(Type serviceType)IServiceScope CreateScope() => RootProvider.CreateScope();
CreateScope總是調用RootProvider的同名方法也就是說每一個新的ServiceProviderEngineScope它們的父節點都是同一個。也就是ServieProvider。ServiceProvider作為所以ServiceProviderEngineScope的父節點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實現了此介面

