DOTNET CORE源码分析之IOC容器结果获取内容补充
补充一下ServiceProvider的内容
可能上一篇文章DOTNET CORE源码分析之IServiceProvider、ServiceProvider、IServiceProviderEngine、ServiceProviderEngine和ServiceProviderEngineScope 中还没有关联上ServiceProvider和ServiceCollection就直接通过GetService获取了值,这样不科学啊。其实是有关联的,请看一下上篇文章同样存在的一个代码段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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的构造函数,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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的工厂,具体作用下如下代码中:
1 2 3 4 5 6 7 8 9 | 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实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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获取最终结果。
接着介绍昨天没完成的内容
昨天介绍到这个获取服务的函数,如下:
1 2 3 4 5 6 7 8 9 10 11 | 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方法如下:
1 2 3 4 | public object Resolve(IServiceCallSite callSite, ServiceProviderEngineScope scope) { return this .VisitCallSite(callSite, scope); } |
其中VisitCallSite就是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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())); } } |
然后:
1 2 3 4 5 6 | protected override object VisitConstant( ConstantCallSite constantCallSite, ServiceProviderEngineScope scope) { return constantCallSite.DefaultValue; } |
这个constantCallSite.Defaultvalue就是需要的返回结果了。
上述的源码过程解析如下代码:
1 2 3 4 | IServiceCollection serviceCollection = new ServiceCollection(); serviceCollection.AddSingleton( typeof ( string ), "lizizhang" ); ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider(); string name = ( string )serviceProvider.GetService( typeof ( string )); |
如果错误之处,请及时指正!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构