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

通过源码我们可以看到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扩展方法,本质是调用的IServiceScopeFactoryCreateScope方法 。
接下来我们就看看下IServiceScopeFactory默认实现类中关于CreateScope()方法的定义,在ServiceProviderEngineScope类中[点击查看源码]
internal ServiceProvider RootProvider { get; }public IServiceScope CreateScope() => RootProvider.CreateScope();这里毫无疑问了RootProvider属性里的实例都是来自根容器 , 而CreateScope()方法则是调用的ServiceProviderCreateScope()方法 。看下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实例不是根作用域,也就是我们说的子作用域 。
大致看一下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;    }}

推荐阅读