DOTNET CORE源码分析之IOC容器结果获取内容补充
李志章 人气:0补充一下ServiceProvider的内容
可能上一篇文章DOTNET CORE源码分析之IServiceProvider、ServiceProvider、IServiceProviderEngine、ServiceProviderEngine和ServiceProviderEngineScope 中还没有关联上ServiceProvider和ServiceCollection就直接通过GetService获取了值,这样不科学啊。其实是有关联的,请看一下上篇文章同样存在的一个代码段:
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"); } }
是的在这个构造函数中第一个参数:IEnumerable<ServiceDescriptor> serviceDescriptors,这个就是ServiceCollection的对应参数,这样,保存了用户添加的注入信息就和ServiceProviderEngine关联上了,然后ServiceProviderEngine可以为调用方提供数据,换句话说,ServiceProvider不是直接提供数据响应,而是借用ServiceProviderEngine的子类来提供,并且提供了ServiceProviderMode中提供的几种方式。
我们再看看ServiceProviderMode的构造函数,如下:
protected ServiceProviderEngine( IEnumerable<ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback) { this._createServiceAccessor = new Func<Type, Func<ServiceProviderEngineScope, object>>(this.CreateServiceAccessor); this._callback = callback; this.Root = new ServiceProviderEngineScope(this); this.RuntimeResolver = new CallSiteRuntimeResolver(); this.CallSiteFactory = new CallSiteFactory(serviceDescriptors); this.CallSiteFactory.Add(typeof (IServiceProvider), (IServiceCallSite) new ServiceProviderCallSite()); this.CallSiteFactory.Add(typeof (IServiceScopeFactory), (IServiceCallSite) new ServiceScopeFactoryCallSite()); this.RealizedServices = new ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>>(); }
这个过程做了很多初始化,我们把关注点集中在这一句:this.CallSiteFactory = new CallSiteFactory(serviceDescriptors),这句把ServiceCollection传递给了CallSiteFactory。CallSiteFactory是创建ServiceCallSite的工厂,具体作用下如下代码中:
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); }
这里的IServiceCallSite callSite = this.CallSiteFactory.CreateCallSite(serviceType, new CallSiteChain()) 函数CreateCallSite实现如下:
internal IServiceCallSite CreateCallSite( Type serviceType, CallSiteChain callSiteChain) { lock (this._callSiteCache) { IServiceCallSite serviceCallSite1; if (this._callSiteCache.TryGetValue(serviceType, out serviceCallSite1)) return serviceCallSite1; IServiceCallSite serviceCallSite2; try { callSiteChain.CheckCircularDependency(serviceType); serviceCallSite2 = this.TryCreateExact(serviceType, callSiteChain) ?? this.TryCreateOpenGeneric(serviceType, callSiteChain) ?? this.TryCreateEnumerable(serviceType, callSiteChain); } finally { callSiteChain.Remove(serviceType); } this._callSiteCache[serviceType] = serviceCallSite2; return serviceCallSite2; } }
其中this.TryCreateExact(serviceType, callSiteChain) ?? this.TryCreateOpenGeneric(serviceType, callSiteChain) ?? this.TryCreateEnumerable(serviceType, callSiteChain) 这个返回值是带有结果的ServiceCallSite,然后通过这个ServiceCallSite获取最终结果。
接着介绍昨天没完成的内容
昨天介绍到这个获取服务的函数,如下:
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); }); }
关注点停留在this.RuntimeResolver.Resolve(callSite, scope),这个函数在调用过程的时候带有两个参数callSite和scope,callSite就是刚刚介绍的ServiceCallSite,Scope是ServiceProviderEngineScope。RuntimeResolver是CallSiteRuntimeResolver的实例,Resolve方法如下:
public object Resolve(IServiceCallSite callSite, ServiceProviderEngineScope scope) { return this.VisitCallSite(callSite, scope); }
其中VisitCallSite就是:
protected virtual TResult VisitCallSite(IServiceCallSite callSite, TArgument argument) { switch (callSite.Kind) { case CallSiteKind.Factory: return this.VisitFactory((FactoryCallSite) callSite, argument); case CallSiteKind.Constructor: return this.VisitConstructor((ConstructorCallSite) callSite, argument); case CallSiteKind.Constant: return this.VisitConstant((ConstantCallSite) callSite, argument); case CallSiteKind.IEnumerable: return this.VisitIEnumerable((IEnumerableCallSite) callSite, argument); case CallSiteKind.ServiceProvider: return this.VisitServiceProvider((ServiceProviderCallSite) callSite, argument); case CallSiteKind.Scope: return this.VisitScoped((ScopedCallSite) callSite, argument); case CallSiteKind.Transient: return this.VisitTransient((TransientCallSite) callSite, argument); case CallSiteKind.CreateInstance: return this.VisitCreateInstance((CreateInstanceCallSite) callSite, argument); case CallSiteKind.ServiceScopeFactory: return this.VisitServiceScopeFactory((ServiceScopeFactoryCallSite) callSite, argument); case CallSiteKind.Singleton: return this.VisitSingleton((SingletonCallSite) callSite, argument); default: throw new NotSupportedException(string.Format("Call site type {0} is not supported", (object) callSite.GetType())); } }
然后:
protected override object VisitConstant( ConstantCallSite constantCallSite, ServiceProviderEngineScope scope) { return constantCallSite.DefaultValue; }
这个constantCallSite.Defaultvalue就是需要的返回结果了。
加载全部内容