通过源码我们可以看到AsyncServiceScope
本身是包装了IServiceScope
实例,它本身也是实现了IServiceScope
接口并且同时IAsyncDisposable
接口以便可以异步调用释放 。相信大家都知道,实现了IDispose
接口可以使用using IServiceScope scope = HttpContext.RequestServices.CreateScope()
的方式,它编译完之后其实是
IServiceScope scope = HttpContext.RequestServices.CreateScope();try{ //具体操作}finally{ scope.Dispose();}实现了IAsyncDisposable
接口可以使用await using (AsyncServiceScope scope2 = scopeProvider.CreateAsyncScope())
的方式,它编译完的代码则是
AsyncServiceScope scope2 = scopeProvider.CreateAsyncScope();try{ //具体操作}finally{ await scope2.DisposeAsync();}打消了这个疑虑,相信大家对它们的关系有了了解,本质就是包装了一下IServiceScope
实例 。
由创建开始接下来我们可以专心的看一下IServiceScope
相关的实现,IServiceScope
的创建则是来自IServiceProvider
的扩展方法CreateScope()
,首先看下它的定义[点击查看源码]
public static IServiceScope CreateScope(this IServiceProvider provider){ return provider.GetRequiredService<IServiceScopeFactory>().CreateScope();}好吧,短短的一行代码,我们可以得到两个比较重要的信息
- 首先获取到的
IServiceScopeFactory
实例,看过上篇文章的可以知道 , 默认情况通过IServiceScopeFactory
实例获取的是根容器
的实例 。
- 其次
IServiceProvider
的CreateScope扩展方法,本质是调用的IServiceScopeFactory
的CreateScope
方法 。
CreateScope()
方法的定义,在ServiceProviderEngineScope
类中[点击查看源码]internal ServiceProvider RootProvider { get; }public IServiceScope CreateScope() => RootProvider.CreateScope();这里毫无疑问了
RootProvider
属性里的实例都是来自根容器 , 而CreateScope()
方法则是调用的ServiceProvider
的CreateScope()
方法 。看下ServiceProvider
类的CreateScope方法定义[点击查看源码]private bool _disposed;internal IServiceScope CreateScope(){ //判断当前ServiceProvider是否被释放 if (_disposed) { //如果已经释放则直接抛出异常 ThrowHelper.ThrowObjectDisposedException(); } //创建ServiceProviderEngineScope实例 return new ServiceProviderEngineScope(this, isRootScope: false);}通过上面的代码我们可以看到
CreateScope()
方法,本质是创建了一个ServiceProviderEngineScope
方法实例 。通过创建的这一行代码,好巧不巧又可以得到两个重要的信息 。- 一是ServiceProviderEngineScope构造函数的第一个参数 , 传递的是当前的ServiceProvider实例 。
- 二是ServiceProviderEngineScope构造函数的第二个参数叫
isRootScope
值给的是false
,说明当前ServiceProviderEngineScope实例不是根作用域,也就是我们说的子作用域 。
internal sealed class ServiceProviderEngineScope : IServiceScope, IServiceProvider, IAsyncDisposable, IServiceScopeFactory{ internal Dictionary<ServiceCacheKey, object> ResolvedServices { get; } internal object Sync => ResolvedServices; internal ServiceProvider RootProvider { get; } public bool IsRootScope { get; } //IServiceProvider的ServiceProvider属性则是赋值的当前实例 public IServiceProvider ServiceProvider => this; public ServiceProviderEngineScope(ServiceProvider provider, bool isRootScope) { //用来存储当前作用域管理的对象实例 ResolvedServices = new Dictionary<ServiceCacheKey, object>(); //创建当前实例的根容器 RootProvider = provider; //标识当前作用域是否是根容器 IsRootScope = isRootScope; }}
推荐阅读
- 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 发布,倒计时一个月发布正式版