前言自从.Net Core引入IOC相关的体系之后,关于它的讨论就从来没有停止过,因为它是.Net Core体系的底层框架,你只要使用了.Net Core的时候就必然会用到它 。当然关于使用它的过程中产生的问题也从来没停止过 。我对待问题的态度向来都是,如果你踩到了坑,说明你还没有足够了解它 , 所以我们对它认知的突破,很多时候是遇到了问题并解决了问题 。今天的话题呢 , 也是一个群友在研究.Net Core作用域的过程中产生的疑问,博主呢对这个问题也很有兴趣,就借此机会探究了一下,把自己研究结果分享给大家 。
简单演示在日常的开发中使用CreateScope()
或CreateAsyncScope()
的场景可能没有那么多 , 但是在ASP.NET Core底层的话这是核心设计,在上篇文章<解决ASP.NET Core在Task中使用IServiceProvider的问题>中提到过,ASP.NET Core会为每次请求创建一个Scope
,也就是咱们这次提到的作用域 。使用的方法有很简单 , 本质就是IServiceProvider
的一个扩展方法 。咱们今天主要说的就是ServiceLifetime.Scoped
这个比较特殊的生命周期,在Scope内是如何工作的,原始点的写法其实就是
IServiceCollection services = new ServiceCollection();services.AddScoped<Person>(provider => new() { Id = 1, Name = "yi念之间", Sex = "Man" });IServiceProvider serviceProvider = services.BuildServiceProvider();using (IServiceScope serviceScope = serviceProvider.CreateScope()){ var personOne = serviceScope.ServiceProvider.GetService<Person>(); Console.WriteLine(person.Name);}如果在ASP.NET Core框架里那玩法就多了,只要有IServiceProvide
的地方都可以使用CreateScope()
或CreateAsyncScope()
方法 , 简单演示一下,但是如果感觉自己把握不住的话还是提前自己试验一下
[HttpGet]public async Task<object> JudgeScope([FromServices]IServiceProvider scopeProvider){ using IServiceScope scope = HttpContext.RequestServices.CreateScope(); Person person = scope.ServiceProvider.GetService<Person>(); await using (AsyncServiceScope scope2 = scopeProvider.CreateAsyncScope()) { Person person2 = scope2.ServiceProvider.GetService<Person>(); } return person;}源码探究通过上面的示例,我们可以看到其实关于IServiceScope
的操作部分就是三个核心 。
- 通过
CreateScope()
或CreateAsyncScope()
方法创建服务作用域 。
- 使用
GetService
相关的方法创建需要的对象实例 。
- 用完了作用域之后通过使用
Dispose()
或者DisposeAsync()
方法(using的方式同理)释放作用域 。
CreateScope()
方法创建出来的是IServiceScope
实例,使用CreateAsyncScope
方法创建的是AsyncServiceScope
实例 。咱们这里先来说一下AsyncServiceScope
和IServiceScope
的关系,看了之后大家就不用惦记它了,先来看一下CreateAsyncScope()
方法的定义[点击查看源码]public static AsyncServiceScope CreateAsyncScope(this IServiceProvider provider){ return new AsyncServiceScope(provider.CreateScope());}方法就是返回
AsyncServiceScope
实例,接下来来看一下这个类的定义[点击查看源码]public readonly struct AsyncServiceScope : IServiceScope, IAsyncDisposable{ private readonly IServiceScope _serviceScope; public AsyncServiceScope(IServiceScope serviceScope) { //AsyncServiceScope也是IServiceScope实例构建起来的 _serviceScope = serviceScope ?? throw new ArgumentNullException(nameof(serviceScope)); } //ServiceProvider也是直接在IServiceScope实例中直接获取的 public IServiceProvider ServiceProvider => _serviceScope.ServiceProvider; //同步释放 public void Dispose() { _serviceScope.Dispose(); } //异步释放 public ValueTask DisposeAsync() { //因为IAsyncDisposable的ServiceProvider能继续创建作用域 //使用CreateScope或CreateAsyncScope方法 if (_serviceScope is IAsyncDisposable ad) { return ad.DisposeAsync(); } _serviceScope.Dispose(); return default; }}
推荐阅读
- 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 发布,倒计时一个月发布正式版