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

下大致看一下,因为接下来会涉及到ServiceProviderEngineScope这个类 。到目前为止涉及到了两个比较重要的类ServiceProviderServiceProviderEngineScope , 它们都是实现了IServiceProvider接口 。看起来有点乱的样子,不过我们可以姑且这么理解 。ServiceProvider是IServiceProvider的直系实现类 , 作为IServiceProvider根容器的实现 。ServiceProviderEngineScope是用于,通过IServiceProvider创建作用域时表现出来的实例,也就是非根容器的实例 。
探究获取方法关于上面的介绍,我们其实探究了一点serviceProvider.CreateScope(),接下来我们就需要看一下关于获取的相关操作,也就是GetService方法相关,它的使用形式是serviceScope.ServiceProvider.GetService<T>() 。上面我们提到过ServiceProviderEngineScopeServiceProvider属性实例则是当前ServiceProviderEngineScope的实例,所以我们直接去看ServiceProviderEngineScopeGetService方法[点击查看源码]
internal sealed class ServiceProviderEngineScope : IServiceScope, IServiceProvider, IAsyncDisposable, IServiceScopeFactory{    private bool _disposed;    internal ServiceProvider RootProvider { get; }    public object GetService(Type serviceType)    {        //判断当前实例是否释放        if (_disposed)        {            //如果已经释放则直接抛出异常            ThrowHelper.ThrowObjectDisposedException();        }        return RootProvider.GetService(serviceType, this);    }}看着挺乱的 , 各种跳转各种调用 。不过本质只设计到两个类ServiceProviderServiceProviderEngineScope,先说明一下,省的大家看着整蒙圈了 。通过最后一句代码,我们又能得到两个比较重要的信息 。

  • ServiceProviderEngineScope的GetService方法,本质是在调用RootProvider的GetService方法 。通过前面咱们的源码分析可以知道RootProvider属性的值是ServiceProvider实例也就是代表的根容器 。
  • 调用RootProvider的GetService方法的时候传递了当前ServiceProviderEngineScope实例 。
接下来就可以直接找到ServiceProvider的GetService方法了,看一下里面的具体相关实现[点击查看源码]
public sealed class ServiceProvider : IServiceProvider, IDisposable, IAsyncDisposable{    private bool _disposed;    private ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>> _realizedServices;    private readonly Func<Type, Func<ServiceProviderEngineScope, object>> _createServiceAccessor;    internal ServiceProviderEngine _engine;    internal ServiceProvider()    {      _createServiceAccessor = CreateServiceAccessor;      _realizedServices = new ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>>();    }    internal object GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)    {        //判断当前实例是否释放        if (_disposed)        {            ThrowHelper.ThrowObjectDisposedException();        }        //缓存获取服务实例委托的字典,值为要获取实例的类型,值是创建实例的委托        //_createServiceAccessor本质是CreateServiceAccessor方法委托        Func<ServiceProviderEngineScope, object> realizedService = _realizedServices.GetOrAdd(serviceType, _createServiceAccessor);        OnResolve(serviceType, serviceProviderEngineScope);        DependencyInjectionEventSource.Log.ServiceResolved(this, serviceType);        //执行realizedService委托,传递的是ServiceProviderEngineScope实例        var result = realizedService.Invoke(serviceProviderEngineScope);        System.Diagnostics.Debug.Assert(result is null || CallSiteFactory.IsService(serviceType));        return result;    }    private Func<ServiceProviderEngineScope, object> CreateServiceAccessor(Type serviceType)    {        //获取ServiceCallSite,其实就是获取要解析对象的实例相关信息        ServiceCallSite callSite = CallSiteFactory.GetCallSite(serviceType, new CallSiteChain());        if (callSite != null)        {            DependencyInjectionEventSource.Log.CallSiteBuilt(this, serviceType, callSite);            OnCreate(callSite);            //咱们当前讨论的是Scope周期对象的问题 , 这个方法描述的是生命周期为ServiceLifetime.Singleton的情况,可以跳过这个逻辑            //如果是单例情况,则直接在根容器中直接去操作对象实例,和当前的ServiceProviderEngineScope无关            if (callSite.Cache.Location == CallSiteResultCacheLocation.Root)            {                object value = CallSiteRuntimeResolver.Instance.Resolve(callSite, Root);                return scope => value;            }            //解析ServiceCallSite里的信息            return _engine.RealizeService(callSite);        }        return _ => null;    }}

推荐阅读