Net6 DI源码分析Part2 Engine,ServiceProvider
2022/2/9 20:23:35
本文主要是介绍Net6 DI源码分析Part2 Engine,ServiceProvider,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
ServiceProvider
ServiceProvider
是对IServiceProvider
实现,它有一个internal
的访问修饰符描述的构造,并需要两个参数IServiceCollection
& ServiceProviderOptions
。所以可以通过 ServiceCollectionContainerBuilderExtensions
提供的扩展方法和DefaultServiceProviderFactory工厂类创建实例。
属性
Func<Type, Func<ServiceProviderEngineScope, object>> _createServiceAccessor
ServiceProviderEngine _engine;
ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>> _realizedServices;
CallSiteFactory CallSiteFactory { get; }
ServiceProviderEngineScope Root { get; }
CallSiteValidator _callSiteValidator;
默认"创建服务存取器"的“工厂方法”
方法
-
void Dispose()
很简单,做了一个事情,调用root
的对应Dispose。清理根容器构造出来的对象 -
void OnCreate(ServiceCallSite callSite)
此方法被用于每次通过CallSiteFactory创建出来的callsite进行验证然后使用_callSiteValidator去验证callsite
。 -
object GetService(Type serviceType)
很简单,调用同名方法,把root作为serviceProviderEngineScope传入。也就是你直接build出来的provider获取的服务均是root提供(废话)也经常被成为root provider(根容器的provider)。其Singleton
、Scoped
类型的生命周期相同。 -
internal GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
很简单,根据type去realizedService如果有值拿对应的“创建服务存取器”否则创建一个默认的,也就是构造函数中初始化的 然后执行委托,把对应的serviceProviderEngineScope传入。
存取器内部会有对应的engine。并把传入参数给engine。engine内部回把创建好的对象放入这个serviceProviderEngineScope内。Func<ServiceProviderEngineScope, object> realizedService = _realizedServices.GetOrAdd(serviceType, _createServiceAccessor); OnResolve(serviceType, serviceProviderEngineScope); var result = realizedService.Invoke(serviceProviderEngineScope); return result;
-
Func<ServiceProviderEngineScope, object> CreateServiceAccessor(Type serviceType)
作为默认的“创建服务存取器”工厂方法做了如下事情- 通过CallSiteFactory获取对应的ServiceCallSite,并传入CallSiteChain。
CallSiteChain
防止循环依赖项 - 得到ServiceCallSite后调用OnCreate验证ServiceCallSite合规性。
- 如果是CallSiteResultCacheLocation.Root单例的,固定通过
CallSiteRuntimeResolver
(RuntimeServiceProviderEngine引擎的符类)产出物委托。算是对“单例”的优化。 - 其它生命周期通过_engine的RealizeService产出物委托。
ServiceCallSite callSite = CallSiteFactory.GetCallSite(serviceType, new CallSiteChain()); OnCreate(callSite); if (callSite.Cache.Location == CallSiteResultCacheLocation.Root) { object value = CallSiteRuntimeResolver.Instance.Resolve(callSite, Root); return scope => value; } return _engine.RealizeService(callSite);
- 通过CallSiteFactory获取对应的ServiceCallSite,并传入CallSiteChain。
-
IServiceScope CreateScope()
;
ServiceProvider作为所以ServiceProviderEngineScope的父节点
return new ServiceProviderEngineScope(this, isRootScope: false);
就算new 了一个新的ServiceProviderEngineScope其内部还是调用this指向的当前serviceProvider的CreateScope去创建对象.
-
ServiceProviderEngine GetEngine()
如何选择引擎,如果是NETFRAMEWORK ,NETSTANDARD2_0 并且支持DynamicCodeCompiled使用DynamicServiceProviderEngine引擎,否则使用RuntimeServiceProviderEngine- DynamicServiceProviderEngine:DynamicServiceProviderEngine的特性是如果同一个类型同一时刻需要创建多次,那么它会使用ILEmitResolverBuilder/ExpressionResolverBuilder
- RuntimeServiceProviderEngineRuntimeServiceProviderEngine内部调用CallSiteRuntimeResolver创建对象 此class 是应用使用反射创建。
ServiceProviderEngine engine; #if NETFRAMEWORK || NETSTANDARD2_0 engine = new DynamicServiceProviderEngine(this); #else if (RuntimeFeature.IsDynamicCodeCompiled) { engine = new DynamicServiceProviderEngine(this); } else { // Don't try to compile Expressions/IL if they are going to get interpreted engine = RuntimeServiceProviderEngine.Instance; } #endif return engine;
-
构造方法
- 初始化
Root
GetEngine
构造服务引擎。- 初始化默认的
_createServiceAccessor
为CreateServiceAccessor
。 - _realizedServices为每个服务缓存一个create Service Accessor(
Func<ServiceProviderEngineScope, object>
) 以Type作为key,默认为_createServiceAccessor
也就是CreateServiceAccessor
。 - 提供内部服务注册信息
- 根据
ServiceProviderOptions Options
初始化验证
Root = new ServiceProviderEngineScope(this, isRootScope: true); _engine = GetEngine(); _createServiceAccessor = CreateServiceAccessor; _realizedServices = new ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>>(); CallSiteFactory = new CallSiteFactory(serviceDescriptors); CallSiteFactory.Add(typeof(IServiceProvider), new ServiceProviderCallSite()); CallSiteFactory.Add(typeof(IServiceScopeFactory), new ConstantCallSite(typeof(IServiceScopeFactory), Root)); CallSiteFactory.Add(typeof(IServiceProviderIsService), new ConstantCallSite(typeof(IServiceProviderIsService), CallSiteFactory)); if (options.ValidateScopes) { _callSiteValidator = new CallSiteValidator(); } if (options.ValidateOnBuild) { foreach (ServiceDescriptor serviceDescriptor in serviceDescriptors) { ValidateService(serviceDescriptor); } }
- 初始化
这里ServiceProivder的功能很明确单一职责,提供服务,创建Scope,提供引擎,即使
ServiceProviderEngineScope
也有同名方法,但最终都依赖于ServiceProivder。它们仅仅是包装了以下。
ServiceProviderEngineScope
它实现了IServiceScope
IServiceProvider
IServiceScopeFactory
所以它可以获取服务,也可以创建Scope。
属性。
private List<object> _disposables;
bool IsRootScope
internal ServiceProvider RootProvider
internal Dictionary<ServiceCacheKey, object> ResolvedServices { get; }
方法。object GetService(Type serviceType)
IServiceScope CreateScope() => RootProvider.CreateScope();
CreateScope总是调用RootProvider的同名方法也就是说每一个新的ServiceProviderEngineScope它们的父节点都是同一个。也就是ServieProvider。ServiceProvider作为所以ServiceProviderEngineScope的父节点void Dispose()
ServiceProviderEngine
一抽象类唯一的方法为RealizeService 主要这里它仅仅返回的是一个委托,此委托的具体执行由ServiceProvider
的GetService
执行
public abstract Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite);
DynamicServiceProviderEngine
该类继承了CompiledServiceProviderEngine.并重写了父类的RealizeService,其内部还是通过CallSiteRuntimeResolver服务类去创建服务,但如果统一时刻某一类型被创建多次时,它会做出替换掉该类型的“创建服务存取器”为 base.RealizeService(callSite)也就是CompiledServiceProviderEngine.RealizeService
可以说DynamicServiceProviderEngine
职责是根据某一个Type的使用频率给出个对应类型的“创建服务存取器” ,不同的“创建服务存取器” 内使用了不同的引擎。
CompiledServiceProviderEngine
CompiledServiceProviderEngine
是对ServiceProviderEngine
的实现之一
一个属性ResolverBuilder
和一个RealizeService
方法
ResolverBuilder 它通过环境去构造出具体的属性ILEmitResolverBuilder
/ExpressionResolverBuilder
调用RealizeService
方法是仅返回对应ResolverBuilder
的产出物的委托。GetService
internal abstract class CompiledServiceProviderEngine : ServiceProviderEngine { #if IL_EMIT public ILEmitResolverBuilder ResolverBuilder { get; } #else public ExpressionResolverBuilder ResolverBuilder { get; } #endif public CompiledServiceProviderEngine(ServiceProvider provider) { ResolverBuilder = new(provider); } public override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite) => ResolverBuilder.Build(callSite); }
RuntimeServiceProviderEngine
同样也是对抽象类ServiceProviderEngine的实现,重写抽象方法后,它内部直接返回CallSiteRuntimeResolver
的Resolve方法的产出物的委托。
public override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite) { return scope => { return CallSiteRuntimeResolver.Instance.Resolve(callSite, scope); }; }
>ServiceProviderEngine.Resolve总结
Engine的Resolve方法返回的均是委托最终在serviceProivder的GetService中执行,得到实例对象也就是我们的最终交给使用者的服务。engine创建对象依赖的均是ServiceCallSite它是由CallSiteFactory根据Type创建的。
IServiceScopeFactory
唯一一个方法IServiceScope CreateScope();
,ServiceProviderEngineScope
实现了此接口
IServiceScope: IDisposable
唯一一个属性IServiceProvider ServiceProvider { get; }
,ServiceProviderEngineScope
实现了此接口
这篇关于Net6 DI源码分析Part2 Engine,ServiceProvider的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享