细聊.Net Core中IServiceScope的工作方式

前言自从.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的方式同理)释放作用域 。
先说AsyncServiceScope为了怕大家心里有疑虑 , 因为使用CreateScope()方法创建出来的是IServiceScope实例,使用CreateAsyncScope方法创建的是AsyncServiceScope实例 。咱们这里先来说一下AsyncServiceScopeIServiceScope的关系,看了之后大家就不用惦记它了,先来看一下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;    }}

推荐阅读