最後來看看前面一直說的 Engine(工作引擎) ,工作引擎介面是 在`ServiceProvider IServiceProviderEngine`介面和其實現類的整體結構 IServiceProviderEngine類型繼承關係 繼承了 介面,也就是說工作引擎也具有 GetService() 方 ...
最後來看看前面一直說的Engine(工作引擎),工作引擎介面是IServiceProviderEngine
在ServiceProvider
的構造函數中看到了根據指定的Mode創建了不同的實現類,下麵先來看一下IServiceProviderEngine
介面和其實現類的整體結構
IServiceProviderEngine類型繼承關係
internal interface IServiceProviderEngine : IDisposable, IServiceProvider
{
IServiceScope RootScope { get; }
}
`IServiceProvderEngine這個介面`繼承了`IServiceProvider`介面,也就是說工作引擎也具有**GetService()**方法,在此介面中具有一個`IServiceScope`類型的**RootScope**,而這個屬性則代表是**根容器**
`IServiceScope`代表一個容器介面,這個介面中具有一個`IServiceProvider`類型的屬性,返回真正表示容器的一個`IServiceProvider`類型
public interface IServiceScope : IDisposable
{
/// <summary>
/// The <see cref="System.IServiceProvider"/> used to resolve dependencies from the scope.
/// </summary>
IServiceProvider ServiceProvider { get; }
}
IServiceProviderEngine整體結構
IServiceProviderEngine
- ServiceProviderEngine
- CompiledServiceProviderEngine
- DynamicServiceProviderEngine
- RuntimeServiceProviderEngine
- ILEmitServiceProviderEngine
- ExpressionsServiceProviderEngine
上面是目前整個引擎結構,但是前面說過目前只用到了`DynamicServiceProviderEngine`,但是我們看整個類型會看到其實在這幾個派生類型中只有一個實現方法`RealizeService(ServiceCallSite callSite)`,而整體結構都是在基類`ServiceProviderEngine`類型中,下麵來看看這個基類類型
ServiceProviderEngine
`ServiceProviderEngine`類型是整個結構的核心類型,但是這個類也是一個很簡單的類,這個類只是調用`CallSiteFactory`和`CallSiteRuntimeResolver`,由下圖可以看到這個類型是一個抽象類,並且實現了`IServiceProviderEngine`和`IServiceScopeFactory`介面介面
`IServiceScopeFactory`這個介面提供了一個創建子容器方法我們已知道`IServiceProviderEngine`介面*繼承*了`IServiceProvider`介面,那麼也就是說在`ServiceProviderEngine`已經具備以下兩個功能
1.獲取服務實例對象
2.創建子容器
internal abstract class ServiceProviderEngine : IServiceProviderEngine, IServiceScopeFactory{}
// 創建子容器介面
public interface IServiceScopeFactory
{
//
IServiceScope CreateScope();
}
下麵首先來看一下此類中擁有的欄位+屬性,這些屬性都是在構造器中進行了實例化
_callback:
這個欄位就是頂級容器時檢查scoped生命周期的訪問者對象,這個從
ServiceProvider
類中時進行傳入的,在這裡並不細講這個類型RealizedServices:
這個屬性是緩存根據容器獲取服務實例對象委托,其中Key為ServiceType
_createServiceAccessor:
這是一個根據類型獲取一個根據容器獲取服務實例對象的委托,可以看到使用了一個CreateServiceAccessor()進行賦值,CreateServiceAccessor()是此類型的一個核心方法,下麵介紹
CallSiteFactory:
ServiceCallSite
工廠類型,在構造器中實例化,可以看到實例化時將serviceDescriptors進行傳入,並且可以看到在構造器中向此實例對象中添加了一個IServiceProvider
和IServiceScopeFactory
RuntimeResolver:
這個屬性是是獲取服務實例的訪問者對象,可以看到在構造器中進行傳入
Root:
Root代表是一個頂級容器
ServiceProviderEngineScope
類型則是一個具體的容器類型,這個類型中緩存了所有的具體服務實例對象,這個類型實現了IServiceScope
介面,從下麵代碼可以看到RootScope
其實就是直接返回了Root
屬性RootScope:
這也是一個根容器實例對象,直接返回的Root屬性
// 頂級容器時scoped生命周期實例檢查策略
private readonly IServiceProviderEngineCallback _callback;
// 根據類型創建構建服務的委托
private readonly Func<Type, Func<ServiceProviderEngineScope, object>> _createServiceAccessor;
// 此實例是否被銷毀
private bool _disposed;
// 緩存根據容器獲取服務實例的委托, Key為註冊類型
internal ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>> RealizedServices { get; }
// CallSite工廠類屬性,此類型用於根據指定實例化方式來創建對應的CallSite
internal CallSiteFactory CallSiteFactory { get; }
// 訪問者對象,此對象對進行實例和緩存具體真正的對象
protected CallSiteRuntimeResolver RuntimeResolver { get; }
// 根容器實例屬性
public ServiceProviderEngineScope Root { get; }
// 根容器實例屬性
public IServiceScope RootScope => Root;
// 構造器
protected ServiceProviderEngine(IEnumerable<ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback)
{
_createServiceAccessor = CreateServiceAccessor;
_callback = callback;
// 實例化根容器
Root = new ServiceProviderEngineScope(this);
// 實例化 CallSite對象訪問者對象
RuntimeResolver = new CallSiteRuntimeResolver();
// 實例化CallSiteFactory類型對象
CallSiteFactory = new CallSiteFactory(serviceDescriptors);
CallSiteFactory.Add(typeof(IServiceProvider), new ServiceProviderCallSite());
// 緩存一個ServiceScopeFactoryCallSite服務,相當於緩存一個ServiceProviderEngine,根據此對象進行創建子容器
CallSiteFactory.Add(typeof(IServiceScopeFactory), new ServiceScopeFactoryCallSite());
// 緩存實例化對象的工廠
RealizedServices = new ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>>();
}
`ServiceProviderEngine`類型中方法只有**GetService()**,**CreateScope()**,**CreateServiceAccessor()**,**Dispose()**和一個抽象方法**RealizeService()**,其中幾個派生類中都只是實現了**RealizeService()**,這個一會再看,下麵來看看`ServiceProviderEngine`類中的這幾個方法
RealizeService:
這個方法由派生類繼承,由指定的
ServiceCallSite
緩存並獲取 服務實例的委托GetService:
這個方法獲取服務實例對象,可以看到具有兩個此方法,並且第一個調用了第二個,並將頂級容器Root進行了傳入,而在第二個方法中,獲取並添加**_createServiceAccessor**委托,然後調用此委托進行獲取服務實例
CreateScope:
這個方法是創建一個子容器對象,在這個方法中可以看到直接 new 了一個容器對象,並將當前對象進行了傳入。從此可以得知為什麼所有容器共用頂級容器的服務註冊了
Dispose:
清除當前對象,並清除頂級容器
CreateServiceAccessor:
這個方法可以看到根據ServiceType進行獲取指定
ServiceCallSite
,然後再調用派生類實現的RealizeService()進行返回
// 抽象類型,子類實現
protected abstract Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite);
public object GetService(Type serviceType) => GetService(serviceType, Root);
internal object GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
{
if (_disposed)
ThrowHelper.ThrowObjectDisposedException();
// 添加並獲取根據容器對象實例化對象的方法,其方法由子類進行重寫
var realizedService = RealizedServices.GetOrAdd(serviceType, _createServiceAccessor);
// 驗證是否允許進行實例化對象
_callback?.OnResolve(serviceType, serviceProviderEngineScope);
return realizedService.Invoke(serviceProviderEngineScope);
}
public void Dispose()
{
_disposed = true;
Root.Dispose();
}
// 實例化的子容器
public IServiceScope CreateScope()
{
if (_disposed)
ThrowHelper.ThrowObjectDisposedException();
return new ServiceProviderEngineScope(this);
}
private Func<ServiceProviderEngineScope, object> CreateServiceAccessor(Type serviceType)
{
// 根據基類類型獲取對應的CallSite
var callSite = CallSiteFactory.GetCallSite(serviceType, new CallSiteChain());
if (callSite != null)
{
// 緩存當前註冊
_callback?.OnCreate(callSite);
return RealizeService(callSite);
}
return _ => null;
}
DynamicServiceProviderEngine和CompiledServiceProviderEngine
下麵來看一下`DynamicServiceProviderEngine`和`CompiledServiceProviderEngine`這兩個派生類型,從上面繼承關係可以看到這兩個派生類型是一個繼承關係 `DynamicServiceProviderEngine`繼承於`CompiledServiceProviderEngine`.
internal class DynamicServiceProviderEngine : CompiledServiceProviderEngine{}
在這兩個派生類型中都只是實現了基類的RealizeService(),下麵先來看看CompiledServiceProviderEngine
類的實現
可以看到CompiledServiceProviderEngine
類中具有一個ExpressionResolverBuilder
對象,這個類是使用表達式樹生成結構,這個實例在構造函數進行創建,並且將CallSiteRuntimeResolver
對象,本對象和頂級容器進行了傳入,可以看到在重寫的方法中是調用了ExpressionResolverBuilder
對象的Build()
,這個方法會生成一個Func<ServiceProviderEngineScope,Object>委托,然後緩存此委托,
註:
ExpressionResolverBuilder
這個類挺複雜,我也沒看懂,所以在此不介紹,有興趣的可以直接看源碼
internal abstract class CompiledServiceProviderEngine : ServiceProviderEngine
{
// 表達式樹生成對象
public ExpressionResolverBuilder ExpressionResolverBuilder { get; }
// 構造函數
public CompiledServiceProviderEngine(IEnumerable<ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback) : base(serviceDescriptors, callback)
=> ExpressionResolverBuilder = new ExpressionResolverBuilder(RuntimeResolver, this, Root);
// 重寫RealizeService方法
protected override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite)
{
// 使用表達式樹進行創建一個Func<ServiceProviderEngineScope,Object>委托
var realizedService = ExpressionResolverBuilder.Build(callSite);
// 直接將表達式生成的委托進行替換之前的緩存
RealizedServices[callSite.ServiceType] = realizedService;
return realizedService;
}
}
而在`RuntimeServiceProviderEngine`類中,則只是實現了**RealizeService()**,從下麵代碼可以看出在第一次調用時是直接調用`CallSiteRuntimeResolver`這個訪問者獲取的實例數據,而在第二次才調用的基類,也就是`CompiledServiceProviderEngine`進行了緩存,但是至於為什麼這樣乾,我沒有弄清。。。
internal class DynamicServiceProviderEngine : CompiledServiceProviderEngine
{
public DynamicServiceProviderEngine(
IEnumerable<ServiceDescriptor> serviceDescriptors,
IServiceProviderEngineCallback callback)
: base(serviceDescriptors, callback)
{
}
protected override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite)
{
var callCount = 0;
return scope =>
{
if (Interlocked.Increment(ref callCount) == 2)
{
// 如果當前是第二次調用,則調用父級進行緩存
Task.Run(() => base.RealizeService(callSite));
}
// 調用訪問者進行根據當前容器和CallSite進行實例化服務對象
return RuntimeResolver.Resolve(callSite, scope);
};
}
}