netcore3.0 IServiceCollection 依赖注入系统(二)
上一文中我们主要介绍了依赖注入的几个接口和重要类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方法获取服务的。