因为我们关注的是CallSiteResultCacheLocation.Scope这种情况所以我们重点关注的是VisitScopeCache()这段方法逻辑,CallSiteRuntimeResolver的VisitCache()方法[点击查看源码]
protected override object VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context){ //咱们关注的是Scope的情况,所以重点在VisitCache方法 return context.Scope.IsRootScope ? VisitRootCache(callSite, context) : VisitCache(callSite, context, context.Scope, RuntimeResolverLock.Scope);}//这里的serviceProviderEngine参数就是我们传递进来的ServiceProviderEngineScope实例private object VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType){ bool lockTaken = false; //获取ServiceProviderEngineScope的Sync属性 object sync = serviceProviderEngine.Sync; //获取ServiceProviderEngineScope的ResolvedServices属性 Dictionary<ServiceCacheKey, object> resolvedServices = serviceProviderEngine.ResolvedServices; //加锁 if ((context.AcquiredLocks & lockType) == 0) { Monitor.Enter(sync, ref lockTaken); } try { //判断ServiceProviderEngineScope的ResolvedServices的属性里是否包含该类型实例 //当前作用域内只有一个实例,所以缓存起来 if (resolvedServices.TryGetValue(callSite.Cache.Key, out object resolved)) { return resolved; } //当前Scope没创建过实例的话则创建 resolved = VisitCallSiteMain(callSite, new RuntimeResolverContext { Scope = serviceProviderEngine, AcquiredLocks = context.AcquiredLocks | lockType }); //判断当前类型实例是否是IDispose想实例 serviceProviderEngine.CaptureDisposable(resolved); //给ServiceProviderEngineScope的ResolvedServices的属性添加缓存实例 resolvedServices.Add(callSite.Cache.Key, resolved); return resolved; } finally { if (lockTaken) { Monitor.Exit(sync); } }}protected virtual TResult VisitCallSiteMain(ServiceCallSite callSite, TArgument argument){ //比如我们上面的services.AddScoped<Person>(provider => new() { Id = 1, Name = "yi念之间", Sex = "Man" }) //对应的Kind则是CallSiteKind.Factory switch (callSite.Kind) { case CallSiteKind.Factory: //调用了VisitFactory方法 return VisitFactory((FactoryCallSite)callSite, argument); case CallSiteKind.IEnumerable: return VisitIEnumerable((IEnumerableCallSite)callSite, argument); case CallSiteKind.Constructor: return VisitConstructor((ConstructorCallSite)callSite, argument); case CallSiteKind.Constant: return VisitConstant((ConstantCallSite)callSite, argument); case CallSiteKind.ServiceProvider: return VisitServiceProvider((ServiceProviderCallSite)callSite, argument); default: throw new NotSupportedException(SR.Format(SR.CallSiteTypeNotSupported, callSite.GetType())); }}protected override object VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context){ //调用我们注册的services.AddScoped<Person>(provider => new() { Id = 1, Name = "yi念之间", Sex = "Man" }) //FactoryCallSite的Factory即是provider => new() { Id = 1, Name = "yi念之间", Sex = "Man" } //context.Scope则是我们通过CreateScope创建的实例 //返回的结果就是调用当前委托得到的实例即我们实例中的Person实例 return factoryCallSite.Factory(context.Scope);}
经验总结扩展阅读
- asp.net core web 解决方案多项目模板制作打包总结
- ubuntu-22.04 树莓派Zero 2 W通过.NET6和libusb操作USB读写
- 上 学习ASP.NET Core Blazor编程系列六——新增图书
- Azure DevOps Pipelines部署.Net Core 应用到Kubernetes
- 记一次 .NET 某企业OA后端服务 卡死分析
- .NET 采用 SkiaSharp 生成二维码和图形验证码及图片进行指定区域截取方法实现
- .Net CLR异常简析
- 记一次 .NET 某电子病历 CPU 爆高分析
- .NET 7 RC 2 发布,倒计时一个月发布正式版
- .NET MAUI 社区工具包 1.3版本发布
