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

  • 首先,需要获取ServiceCallSite,在方法GetCallSite()中,其实就是获取要解析对象的实例相关信息 。我们需要知道创建类型实例的时候使用哪种方式(比如我们的Person是使用委托的这种方式),其中也包括该对象创建的类型、创建工厂、生命周期类型 。
  • 然后,得到ServiceCallSite实例之后,我们就可以通过实例创建的信息去创建信息,在方法RealizeService()里 。根据不同类型创建方式和生命周期 , 判断如何创建对象,即对象存放位置 。
  • 最后 , 如果是单例模式,则在根容器中解析这个对象 , 位置当然也是存储在根容器中 , 全局唯一 。如果是瞬时模式,则直接返回创建的对象实例,不进行任何存储,但是需要判断实例是否实现了IDisposable或IAsyncDisposable接口,如果是则加入当前ServiceProviderEngineScope实例的_disposables集合 。如果是Scope模式就比较特殊了 , 因为Scope需要在当前ServiceProviderEngineScope中存储保证当前作用域唯一 , 则需要添加到ResolvedServices属性的字典里,同时也需要判断是否需要添加到_disposables集合里 。
  • 这就可以解释ServiceProviderEngineScope针对不同生命周期的存储方式了,单例的情况创建和存储都是在根容器中,瞬时的情况下则每次都创建新的实例且不进行存储,Scope的情况下则是存储在当前的ResolvedServices中享元起来可以在当前作用域内重复使用 。
    关于结束释放前面咱们看了下关于作用域创建,在做用户获取对象的相关逻辑 。接下来我们来看一下三件套的最后一个步骤,释放逻辑相关的 。这个逻辑比较简单,上面咱们或多或少的也说过了一点,释放分为同步释放和异步释放两种情况,咱们看一下同步释放的相关实现[点击查看源码]
    internal Dictionary<ServiceCacheKey, object> ResolvedServices { get; }internal object Sync => ResolvedServices;private bool _disposed;private List<object> _disposables;public void Dispose(){    List<object> toDispose = BeginDispose();    if (toDispose != null)    {        for (int i = toDispose.Count - 1; i >= 0; i--)        {            //模仿栈模式,最后创建的最先释放            if (toDispose[i] is IDisposable disposable)            {                //释放的正式实现了IDisposable接口的对象                disposable.Dispose();            }            else            {                throw new InvalidOperationException(SR.Format(SR.AsyncDisposableServiceDispose, TypeNameHelper.GetTypeDisplayName(toDispose[i])));            }        }    }}private List<object> BeginDispose(){    //本质就是锁住当前存储对象的集合,不允许进行任何操作    lock (Sync)    {        //如果已经释放过了则直接返回        if (_disposed)        {            return null;        }        DependencyInjectionEventSource.Log.ScopeDisposed(RootProvider.GetHashCode(), ResolvedServices.Count, _disposables?.Count ?? 0);        //先把释放标识设置了        _disposed = true;    }    //判断是否是根容器释放    if (IsRootScope && !RootProvider.IsDisposed())    {        RootProvider.Dispose();    }    return _disposables;}

    推荐阅读