DOTNET CORE源码分析之IServiceProvider、ServiceProvider、IServiceProviderEngine、ServiceProviderEngine和ServiceProviderEngineScope
首先谈一下IServiceProvider
IServiceProvider只提供给了一个根据类型获取对象的功能,试想一下IOC总得有一个找到对象,具体如下
public interface IServiceProvider { object GetService(Type serviceType); }
再谈一下ServiceProvider
ServiceProvider实例化了IServiceProvider,也就是实现了GetService,用于获取容器中实际对象,但是它是借助于IServiceProviderEngine(这个接口稍后再介绍),具体如下:
public object GetService(Type serviceType) { return this._engine.GetService(serviceType); }
另外ServiceCollection中有一个方法BuildServiceProvider(存在于类ServiceCollectionContainerBuilderExtensions中),返回值对象类型就是ServiceProvider
/// <summary> /// Extension methods for building a <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceProvider" /> from an <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />. /// </summary> public static class ServiceCollectionContainerBuilderExtensions { /// <summary> /// Creates a <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceProvider" /> containing services from the provided <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />. /// </summary> /// <param name="services">The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> containing service descriptors.</param> /// <returns>The <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceProvider" />.</returns> public static ServiceProvider BuildServiceProvider( this IServiceCollection services) { return services.BuildServiceProvider(ServiceProviderOptions.Default); } /// <summary> /// Creates a <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceProvider" /> containing services from the provided <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> /// optionaly enabling scope validation. /// </summary> /// <param name="services">The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> containing service descriptors.</param> /// <param name="validateScopes"> /// <c>true</c> to perform check verifying that scoped services never gets resolved from root provider; otherwise <c>false</c>. /// </param> /// <returns>The <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceProvider" />.</returns> public static ServiceProvider BuildServiceProvider( this IServiceCollection services, bool validateScopes) { return services.BuildServiceProvider(new ServiceProviderOptions() { ValidateScopes = validateScopes }); } /// <summary> /// Creates a <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceProvider" /> containing services from the provided <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> /// optionaly enabling scope validation. /// </summary> /// <param name="services">The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> containing service descriptors.</param> /// <param name="options"> /// Configures various service provider behaviors. /// </param> /// <returns>The <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceProvider" />.</returns> public static ServiceProvider BuildServiceProvider( this IServiceCollection services, ServiceProviderOptions options) { if (services == null) throw new ArgumentNullException(nameof (services)); if (options == null) throw new ArgumentNullException(nameof (options)); return new ServiceProvider((IEnumerable<ServiceDescriptor>) services, options); } }
必须要结合一下IServiceProviderEngine、ServiceProviderEngine和ServiceProviderEngineScope对象才能具体知道ServiceProvider是怎么获取IOC容器中的对象了
在使用BuildServiceProvider的时候,最终会调用new ServiceProvider((IEnumerable<ServiceDescriptor>)services,options),然后就是调用如下函数:
internal ServiceProvider( IEnumerable<ServiceDescriptor> serviceDescriptors, ServiceProviderOptions options) { IServiceProviderEngineCallback callback = (IServiceProviderEngineCallback) null; if (options.ValidateScopes) { callback = (IServiceProviderEngineCallback) this; this._callSiteValidator = new CallSiteValidator(); } switch (options.Mode) { case ServiceProviderMode.Dynamic: this._engine = (IServiceProviderEngine) new DynamicServiceProviderEngine(serviceDescriptors, callback); break; case ServiceProviderMode.Runtime: this._engine = (IServiceProviderEngine) new RuntimeServiceProviderEngine(serviceDescriptors, callback); break; case ServiceProviderMode.Expressions: this._engine = (IServiceProviderEngine) new ExpressionsServiceProviderEngine(serviceDescriptors, callback); break; case ServiceProviderMode.ILEmit: this._engine = (IServiceProviderEngine) new ILEmitServiceProviderEngine(serviceDescriptors, callback); break; default: throw new NotSupportedException("Mode"); } }
就是说最终还是根据ServiceProviderMode来判断需要实例化哪种ServiceProviderEngine,现在简单举例DynamicServiceProviderEngine。DynamicServiceProviderEngine最终还是继承ServiceProviderEngine,
所以上面说的GetService其实就是调用了ServiceProviderEngine的GetService
public object GetService(Type serviceType) { return this.GetService(serviceType, this.Root); }
其中this.Root就是实例化的ServiceProviderScope。上面的this.GetService(serviceType,this.Root)会调用如下函数:
internal object GetService( Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) { if (this._disposed) ThrowHelper.ThrowObjectDisposedException(); Func<ServiceProviderEngineScope, object> orAdd = this.RealizedServices.GetOrAdd(serviceType, this._createServiceAccessor); this._callback?.OnResolve(serviceType, (IServiceScope) serviceProviderEngineScope); ServiceProviderEngineScope providerEngineScope = serviceProviderEngineScope; return orAdd(providerEngineScope); }
最终就是调用Func<ServiceProviderEngineScope, object> orAdd = this.RealizedServices.GetOrAdd(serviceType, this._createServiceAccessor);其中RealizedServices是ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>> RealizedServices { get; },this._createServiceAccessor是Func<ServiceProviderEngineScope, object>,通过这个委托根据ServiceProviderEngineScope获取最终的对象,也就是说,如果服务存在的话就从字典中获取,不存在就添加到队列上,并直接返回。另外在实例化ServiceProviderEngine的时候实例化了this._createServiceAccessor = new Func<Type, Func<ServiceProviderEngineScope, object>>(this.CreateServiceAccessor);其中CreateServiceAccessor是一个函数,定义如下:
private Func<ServiceProviderEngineScope, object> CreateServiceAccessor( Type serviceType) { IServiceCallSite callSite = this.CallSiteFactory.CreateCallSite(serviceType, new CallSiteChain()); if (callSite == null) return (Func<ServiceProviderEngineScope, object>) (_ => (object) null); this._callback?.OnCreate(callSite); return this.RealizeService(callSite); }
就DynamicServiceProviderEngine而言,RealizeService的定义如下:
protected override Func<ServiceProviderEngineScope, object> RealizeService( IServiceCallSite callSite) { int callCount = 0; return (Func<ServiceProviderEngineScope, object>) (scope => { if (Interlocked.Increment(ref callCount) == 2) Task.Run<Func<ServiceProviderEngineScope, object>>((Func<Func<ServiceProviderEngineScope, object>>) (() => base.RealizeService(callSite))); return this.RuntimeResolver.Resolve(callSite, scope); }); }
RuntimeResolver是ServiceProviderEngine的一个属性。到此为止,IOC容器的数据就可以获取到了。下篇博客会继续说明this.RuntimeResover.Resolve下的事情。