这里我们看下CallSiteFactory.GetCallSite
方法,先来说一下这个方法是做啥的 。我们要获取某个类型的实例(可以理解为我们演示示例里的Person类),但是我们注册类相关的信息的时候(比如上面的services.AddScoped<Person>(provider => new() { Id = 1, Name = "yi念之间", Sex = "Man" })
)涉及到几种方式,比如AddScoped<T>
和Add<T>(Func<IServiceProvider,object>)
,我们需要知道创建类型实例的时候使用哪种方式(比如我们的Person是使用委托的这种方式),ServiceCallSite正是存储的类型和如何创建这个类型的工厂相关的信息 。我们来看一下GetCallSite
方法的核心操作[点击查看源码]
private readonly ConcurrentDictionary<ServiceCacheKey, ServiceCallSite> _callSiteCache = new ConcurrentDictionary<ServiceCacheKey, ServiceCallSite>();private ServiceCallSite TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, int slot){ if (serviceType == descriptor.ServiceType) { //要获取的类型会被包装成ServiceCacheKey ServiceCacheKey callSiteKey = new ServiceCacheKey(serviceType, slot); //在缓存中获取ServiceCallSite实例,可以理解为设计模式中的享元模式 if (_callSiteCache.TryGetValue(callSiteKey, out ServiceCallSite serviceCallSite)) { return serviceCallSite; } ServiceCallSite callSite; //根据ServiceDescriptor.Lifetime包装ResultCache var lifetime = new ResultCache(descriptor.Lifetime, serviceType, slot); //ServiceDescriptor就是我们添加到IServiceCollection的最终形式 //我们注册服务的时候本质就是在IServiceCollection里添加ServiceDescriptor实例 //AddScope<T>()这种形式 if (descriptor.ImplementationInstance != null) { callSite = new ConstantCallSite(descriptor.ServiceType, descriptor.ImplementationInstance); } //AddScope(Func<IServiceProvider,object>)形式 else if (descriptor.ImplementationFactory != null) { callSite = new FactoryCallSite(lifetime, descriptor.ServiceType, descriptor.ImplementationFactory); } //AddScope<T,TImpl>()形式 else if (descriptor.ImplementationType != null) { callSite = CreateConstructorCallSite(lifetime, descriptor.ServiceType, descriptor.ImplementationType, callSiteChain); } else { throw new InvalidOperationException(SR.InvalidServiceDescriptor); } //将创建的ServiceCallSite缓存起来 return _callSiteCache[callSiteKey] = callSite; } return null;}而解析ServiceCallSite
实例的方法RealizeService(ServiceCallSite)
则是在ServiceProviderEngine
类中,看一下相关实现[点击查看源码]
public override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite){ int callCount = 0; return scope => { //核心代码是Resolve方法,这里的scope则是ServiceProviderEngineScope //即我们上面通过CreateScope()创建的实例 var result = CallSiteRuntimeResolver.Instance.Resolve(callSite, scope); if (Interlocked.Increment(ref callCount) == 2) { _ = ThreadPool.UnsafeQueueUserWorkItem(_ => { try { _serviceProvider.ReplaceServiceAccessor(callSite, base.RealizeService(callSite)); } catch (Exception ex) { //省略掉非核心代码 } }, null); } return result; };}
推荐阅读
- asp.net core web 解决方案多项目模板制作打包总结
- ubuntu-22.04 树莓派Zero 2 W通过.NET6和libusb操作USB读写
- 上 学习ASP.NET Core Blazor编程系列六——新增图书
- Azure DevOps Pipelines部署.Net Core 应用到Kubernetes
- C语言小白刷题
- 记一次 .NET 某企业OA后端服务 卡死分析
- .NET 采用 SkiaSharp 生成二维码和图形验证码及图片进行指定区域截取方法实现
- .Net CLR异常简析
- 记一次 .NET 某电子病历 CPU 爆高分析
- .NET 7 RC 2 发布,倒计时一个月发布正式版