上一文中我們主要介紹了依賴注入的幾個接口和重要類ServiceDescriptor,該類是服務的描述,所有的服務都保存在IServiceCollection接口中,也就是我們的服務注冊就是在該接口中
下面介紹下IServiceCollection接口的實現類ServiceCollection
/// <summary> /// Default implementation of <see cref="IServiceCollection"/>. /// </summary> public class ServiceCollection : IServiceCollection { private readonly List<ServiceDescriptor> _descriptors = new List<ServiceDescriptor>(); /// <inheritdoc /> public int Count => _descriptors.Count; /// <inheritdoc /> public bool IsReadOnly => false; /// <inheritdoc /> public ServiceDescriptor this[int index] { get { return _descriptors[index]; } set { _descriptors[index] = value; } } /// <inheritdoc /> public void Clear() { _descriptors.Clear(); } /// <inheritdoc /> public bool Contains(ServiceDescriptor item) { return _descriptors.Contains(item); } /// <inheritdoc /> public void CopyTo(ServiceDescriptor[] array, int arrayIndex) { _descriptors.CopyTo(array, arrayIndex); } /// <inheritdoc /> public bool Remove(ServiceDescriptor item) { return _descriptors.Remove(item); } /// <inheritdoc /> public IEnumerator<ServiceDescriptor> GetEnumerator() { return _descriptors.GetEnumerator(); } void ICollection<ServiceDescriptor>.Add(ServiceDescriptor item) { _descriptors.Add(item); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// <inheritdoc /> public int IndexOf(ServiceDescriptor item) { return _descriptors.IndexOf(item); } /// <inheritdoc /> public void Insert(int index, ServiceDescriptor item) { _descriptors.Insert(index, item); } /// <inheritdoc /> public void RemoveAt(int index) { _descriptors.RemoveAt(index); } }
該類內部有List<ServiceDescriptor>類型的字段_descriptors,用來保存我們注入的服務信息
我們已經把服務注入好了,那怎么從服務容器里面獲取對應的服務實現呢,下面詳細介紹:
// // 摘要: // Defines a mechanism for retrieving a service object; that is, an object that // provides custom support to other objects. public interface IServiceProvider { // // 摘要: // Gets the service object of the specified type. // // 參數: // serviceType: // An object that specifies the type of service object to get. // // 返回結果: // A service object of type serviceType. -or- null if there is no service object // of type serviceType. object GetService(Type serviceType); }
這里有個重要的接口IServiceProvider,我們的服務解析就是從該接口中獲取的
netcore的服務解析類為:ServiceProvider,
看下詳細代碼:
/// <summary> /// The default IServiceProvider. /// </summary> public sealed class ServiceProvider : IServiceProvider, IDisposable, IServiceProviderEngineCallback, IAsyncDisposable { private readonly IServiceProviderEngine _engine; private readonly CallSiteValidator _callSiteValidator; internal ServiceProvider(IEnumerable<ServiceDescriptor> serviceDescriptors, ServiceProviderOptions options) { IServiceProviderEngineCallback callback = null; if (options.ValidateScopes) { callback = this; _callSiteValidator = new CallSiteValidator(); } switch (options.Mode) { case ServiceProviderMode.Default: #if !NETCOREAPP _engine = new DynamicServiceProviderEngine(serviceDescriptors, callback); #else if (RuntimeFeature.IsSupported("IsDynamicCodeCompiled")) { _engine = new DynamicServiceProviderEngine(serviceDescriptors, callback); } else { // Don't try to compile Expressions/IL if they are going to get interpreted _engine = new RuntimeServiceProviderEngine(serviceDescriptors, callback); } #endif break; case ServiceProviderMode.Dynamic: _engine = new DynamicServiceProviderEngine(serviceDescriptors, callback); break; case ServiceProviderMode.Runtime: _engine = new RuntimeServiceProviderEngine(serviceDescriptors, callback); break; #if IL_EMIT case ServiceProviderMode.ILEmit: _engine = new ILEmitServiceProviderEngine(serviceDescriptors, callback); break; #endif case ServiceProviderMode.Expressions: _engine = new ExpressionsServiceProviderEngine(serviceDescriptors, callback); break; default: throw new NotSupportedException(nameof(options.Mode)); } if (options.ValidateOnBuild) { List<Exception> exceptions = null; foreach (var serviceDescriptor in serviceDescriptors) { try { _engine.ValidateService(serviceDescriptor); } catch (Exception e) { exceptions = exceptions ?? new List<Exception>(); exceptions.Add(e); } } if (exceptions != null) { throw new AggregateException("Some services are not able to be constructed", exceptions.ToArray()); } } } /// <summary> /// Gets the service object of the specified type. /// </summary> /// <param name="serviceType">The type of the service to get.</param> /// <returns>The service that was produced.</returns> public object GetService(Type serviceType) => _engine.GetService(serviceType); /// <inheritdoc /> public void Dispose() { _engine.Dispose(); } void IServiceProviderEngineCallback.OnCreate(ServiceCallSite callSite) { _callSiteValidator.ValidateCallSite(callSite); } void IServiceProviderEngineCallback.OnResolve(Type serviceType, IServiceScope scope) { _callSiteValidator.ValidateResolution(serviceType, scope, _engine.RootScope); } /// <inheritdoc/> public ValueTask DisposeAsync() { return _engine.DisposeAsync(); } }
ServiceProvider構造函數接收兩個參數IEnumerable<ServiceDescriptor> serviceDescriptors, ServiceProviderOptions options,
第一個參數是我們注冊的所有服務,第二個參數是一些配置項
/// <summary> /// Options for configuring various behaviors of the default <see cref="IServiceProvider"/> implementation. /// </summary> public class ServiceProviderOptions { // Avoid allocating objects in the default case internal static readonly ServiceProviderOptions Default = new ServiceProviderOptions(); /// <summary> /// <c>true</c> to perform check verifying that scoped services never gets resolved from root provider; otherwise <c>false</c>. Defaults to <c>false</c>. /// </summary> public bool ValidateScopes { get; set; } /// <summary> /// <c>true</c> to perform check verifying that all services can be created during <code>BuildServiceProvider</code> call; otherwise <c>false</c>. Defaults to <c>false</c>. /// NOTE: this check doesn't verify open generics services. /// </summary> public bool ValidateOnBuild { get; set; } internal ServiceProviderMode Mode { get; set; } = ServiceProviderMode.Default; }
先看下構造函數的第一段代碼
if (options.ValidateScopes) { callback = this; _callSiteValidator = new CallSiteValidator(); }
CallSiteValidator用來做一些驗證操作
IServiceProviderEngine接口:
ServiceProviderEngine抽象類:
internal abstract class ServiceProviderEngine : IServiceProviderEngine, IServiceScopeFactory { private readonly IServiceProviderEngineCallback _callback; private readonly Func<Type, Func<ServiceProviderEngineScope, object>> _createServiceAccessor; private bool _disposed; protected ServiceProviderEngine(IEnumerable<ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback) { _createServiceAccessor = CreateServiceAccessor; _callback = callback; Root = new ServiceProviderEngineScope(this); RuntimeResolver = new CallSiteRuntimeResolver(); CallSiteFactory = new CallSiteFactory(serviceDescriptors); CallSiteFactory.Add(typeof(IServiceProvider), new ServiceProviderCallSite()); CallSiteFactory.Add(typeof(IServiceScopeFactory), new ServiceScopeFactoryCallSite()); RealizedServices = new ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>>(); } internal ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>> RealizedServices { get; } internal CallSiteFactory CallSiteFactory { get; } protected CallSiteRuntimeResolver RuntimeResolver { get; } public ServiceProviderEngineScope Root { get; } public IServiceScope RootScope => Root; public void ValidateService(ServiceDescriptor descriptor) { if (descriptor.ServiceType.IsGenericType && !descriptor.ServiceType.IsConstructedGenericType) { return; } try { var callSite = CallSiteFactory.GetCallSite(descriptor, new CallSiteChain()); if (callSite != null) { _callback?.OnCreate(callSite); } } catch (Exception e) { throw new InvalidOperationException($"Error while validating the service descriptor '{descriptor}': {e.Message}", e); } } public object GetService(Type serviceType) => GetService(serviceType, Root); protected abstract Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite); public void Dispose() { _disposed = true; Root.Dispose(); } public ValueTask DisposeAsync() { _disposed = true; return Root.DisposeAsync(); } internal object GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) { if (_disposed) { ThrowHelper.ThrowObjectDisposedException(); } var realizedService = RealizedServices.GetOrAdd(serviceType, _createServiceAccessor); _callback?.OnResolve(serviceType, serviceProviderEngineScope); DependencyInjectionEventSource.Log.ServiceResolved(serviceType); return realizedService.Invoke(serviceProviderEngineScope); } public IServiceScope CreateScope() { if (_disposed) { ThrowHelper.ThrowObjectDisposedException(); } return new ServiceProviderEngineScope(this); } private Func<ServiceProviderEngineScope, object> CreateServiceAccessor(Type serviceType) { var callSite = CallSiteFactory.GetCallSite(serviceType, new CallSiteChain()); if (callSite != null) { DependencyInjectionEventSource.Log.CallSiteBuilt(serviceType, callSite); _callback?.OnCreate(callSite); return RealizeService(callSite); } return _ => null; } }
ServiceProviderEngine抽象類用於解析服務對應的實現
private readonly Func<Type, Func<ServiceProviderEngineScope, object>> _createServiceAccessor;
該委托解析出對應的服務實現
private Func<ServiceProviderEngineScope, object> CreateServiceAccessor(Type serviceType) { var callSite = CallSiteFactory.GetCallSite(serviceType, new CallSiteChain()); if (callSite != null) { DependencyInjectionEventSource.Log.CallSiteBuilt(serviceType, callSite); _callback?.OnCreate(callSite); return RealizeService(callSite); } return _ => null; }
protected abstract Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite);
里面的抽象方法RealizeService正是解析出服務的實現,具體的實現都各自的實現類中查看
ServiceCallSite抽象類:用於服務的創建
CallSiteFactory對注入的服務IEnumerable<ServiceDescriptor> descriptors進行處理,根據服務的類型獲取對應的ServiceCallSite
ServiceCallSite可以理解為以哪種方式解析該服務
如果ServiceDescriptor的ImplementationInstance不為null,則返回ConstantCallSite
如果ServiceDescriptor的ImplementationFactory不為null,則返回FactoryCallSite
如果ServiceDescriptor的ImplementationType不為null,則返回ConstructorCallSite
再回到ServiceProviderEngine抽象類中
ServiceProviderEngine類中有CallSiteRuntimeResolver類型的RuntimeResolver屬性
internal abstract class CallSiteVisitor<TArgument, TResult> { private readonly StackGuard _stackGuard; protected CallSiteVisitor() { _stackGuard = new StackGuard(); } protected virtual TResult VisitCallSite(ServiceCallSite callSite, TArgument argument) { if (!_stackGuard.TryEnterOnCurrentStack()) { return _stackGuard.RunOnEmptyStack((c, a) => VisitCallSite(c, a), callSite, argument); } switch (callSite.Cache.Location) { case CallSiteResultCacheLocation.Root: return VisitRootCache(callSite, argument); case CallSiteResultCacheLocation.Scope: return VisitScopeCache(callSite, argument); case CallSiteResultCacheLocation.Dispose: return VisitDisposeCache(callSite, argument); case CallSiteResultCacheLocation.None: return VisitNoCache(callSite, argument); default: throw new ArgumentOutOfRangeException(); } } protected virtual TResult VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) { switch (callSite.Kind) { case CallSiteKind.Factory: return VisitFactory((FactoryCallSite)callSite, argument); case CallSiteKind.IEnumerable: return VisitIEnumerable((IEnumerableCallSite)callSite, argument); case CallSiteKind.Constructor: return VisitConstructor((ConstructorCallSite)callSite, argument); case CallSiteKind.Constant: return VisitConstant((ConstantCallSite)callSite, argument); case CallSiteKind.ServiceProvider: return VisitServiceProvider((ServiceProviderCallSite)callSite, argument); case CallSiteKind.ServiceScopeFactory: return VisitServiceScopeFactory((ServiceScopeFactoryCallSite)callSite, argument); default: throw new NotSupportedException($"Call site type {callSite.GetType()} is not supported"); } } protected virtual TResult VisitNoCache(ServiceCallSite callSite, TArgument argument) { return VisitCallSiteMain(callSite, argument); } protected virtual TResult VisitDisposeCache(ServiceCallSite callSite, TArgument argument) { return VisitCallSiteMain(callSite, argument); } protected virtual TResult VisitRootCache(ServiceCallSite callSite, TArgument argument) { return VisitCallSiteMain(callSite, argument); } protected virtual TResult VisitScopeCache(ServiceCallSite callSite, TArgument argument) { return VisitCallSiteMain(callSite, argument); } protected abstract TResult VisitConstructor(ConstructorCallSite constructorCallSite, TArgument argument); protected abstract TResult VisitConstant(ConstantCallSite constantCallSite, TArgument argument); protected abstract TResult VisitServiceProvider(ServiceProviderCallSite serviceProviderCallSite, TArgument argument); protected abstract TResult VisitServiceScopeFactory(ServiceScopeFactoryCallSite serviceScopeFactoryCallSite, TArgument argument); protected abstract TResult VisitIEnumerable(IEnumerableCallSite enumerableCallSite, TArgument argument); protected abstract TResult VisitFactory(FactoryCallSite factoryCallSite, TArgument argument); }
該類可以根據對應的ServiceCallSite解析出服務的實現
ServiceProviderEngine類中的默認實現為CallSiteRuntimeResolver
ServiceProviderEngine抽象類的GetService流程為:
internal ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>> RealizedServices { get; } private readonly Func<Type, Func<ServiceProviderEngineScope, object>> _createServiceAccessor; 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); DependencyInjectionEventSource.Log.ServiceResolved(serviceType); return realizedService.Invoke(serviceProviderEngineScope); } private Func<ServiceProviderEngineScope, object> CreateServiceAccessor(Type serviceType) { var callSite = CallSiteFactory.GetCallSite(serviceType, new CallSiteChain()); if (callSite != null) { DependencyInjectionEventSource.Log.CallSiteBuilt(serviceType, callSite); _callback?.OnCreate(callSite); return RealizeService(callSite); } return _ => null; }
protected abstract Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite);
我們再來看下ServiceProviderEngine抽象類的各個具體實現
1、DynamicServiceProviderEngine
internal abstract class CompiledServiceProviderEngine : ServiceProviderEngine { #if IL_EMIT public ILEmitResolverBuilder ResolverBuilder { get; } #else public ExpressionResolverBuilder ResolverBuilder { get; } #endif public CompiledServiceProviderEngine(IEnumerable<ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback) : base(serviceDescriptors, callback) { #if IL_EMIT ResolverBuilder = new ILEmitResolverBuilder(RuntimeResolver, this, Root); #else ResolverBuilder = new ExpressionResolverBuilder(RuntimeResolver, this, Root); #endif } protected override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite) { var realizedService = ResolverBuilder.Build(callSite); RealizedServices[callSite.ServiceType] = realizedService; return realizedService; } }
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)); } return RuntimeResolver.Resolve(callSite, scope); }; } }
DynamicServiceProviderEngine中
如果Interlocked.Increment(ref callCount) == 2為false,則調用ServiceProviderEngine類中RuntimeResolver屬性的Resolve方法來解析服務
如果為true,則調用CompiledServiceProviderEngine中的RealizeService方法解析服務
這里涉及到ILEmitResolverBuilder和ExpressionResolverBuilder兩個類
要深入了解里面怎么解析出服務的,自己研究下代碼吧。
2、 ExpressionsServiceProviderEngine
internal class ExpressionsServiceProviderEngine : ServiceProviderEngine { private readonly ExpressionResolverBuilder _expressionResolverBuilder; public ExpressionsServiceProviderEngine(IEnumerable<ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback) : base(serviceDescriptors, callback) { _expressionResolverBuilder = new ExpressionResolverBuilder(RuntimeResolver, this, Root); } protected override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite) { var realizedService = _expressionResolverBuilder.Build(callSite); RealizedServices[callSite.ServiceType] = realizedService; return realizedService; } }
3、 ILEmitServiceProviderEngine
internal class ILEmitServiceProviderEngine : ServiceProviderEngine { private readonly ILEmitResolverBuilder _expressionResolverBuilder; public ILEmitServiceProviderEngine(IEnumerable<ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback) : base(serviceDescriptors, callback) { _expressionResolverBuilder = new ILEmitResolverBuilder(RuntimeResolver, this, Root); } protected override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite) { var realizedService = _expressionResolverBuilder.Build(callSite); RealizedServices[callSite.ServiceType] = realizedService; return realizedService; } }
4、 RuntimeServiceProviderEngine
internal class RuntimeServiceProviderEngine : ServiceProviderEngine { public RuntimeServiceProviderEngine(IEnumerable<ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback) : base(serviceDescriptors, callback) { } protected override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite) { return scope => { Func<ServiceProviderEngineScope, object> realizedService = p => RuntimeResolver.Resolve(callSite, p); RealizedServices[callSite.ServiceType] = realizedService; return realizedService(scope); }; } }
我們重新回到ServiceProvider類中來
internal ServiceProvider(IEnumerable<ServiceDescriptor> serviceDescriptors, ServiceProviderOptions options) { IServiceProviderEngineCallback callback = null; if (options.ValidateScopes) { callback = this; _callSiteValidator = new CallSiteValidator(); } switch (options.Mode) { case ServiceProviderMode.Default: #if !NETCOREAPP _engine = new DynamicServiceProviderEngine(serviceDescriptors, callback); #else if (RuntimeFeature.IsSupported("IsDynamicCodeCompiled")) { _engine = new DynamicServiceProviderEngine(serviceDescriptors, callback); } else { // Don't try to compile Expressions/IL if they are going to get interpreted _engine = new RuntimeServiceProviderEngine(serviceDescriptors, callback); } #endif break; case ServiceProviderMode.Dynamic: _engine = new DynamicServiceProviderEngine(serviceDescriptors, callback); break; case ServiceProviderMode.Runtime: _engine = new RuntimeServiceProviderEngine(serviceDescriptors, callback); break; #if IL_EMIT case ServiceProviderMode.ILEmit: _engine = new ILEmitServiceProviderEngine(serviceDescriptors, callback); break; #endif case ServiceProviderMode.Expressions: _engine = new ExpressionsServiceProviderEngine(serviceDescriptors, callback); break; default: throw new NotSupportedException(nameof(options.Mode)); } if (options.ValidateOnBuild) { List<Exception> exceptions = null; foreach (var serviceDescriptor in serviceDescriptors) { try { _engine.ValidateService(serviceDescriptor); } catch (Exception e) { exceptions = exceptions ?? new List<Exception>(); exceptions.Add(e); } } if (exceptions != null) { throw new AggregateException("Some services are not able to be constructed", exceptions.ToArray()); } } }
從構造函數我們看出,根據參數ServiceProviderOptions的Mode屬性,來獲取對應的IServiceProviderEngine接口實現
ServiceProvider類的GetService方法就是調用不同IServiceProviderEngine的GetService方法獲取服務的。