.NETCORE 容器源码讲解

144 阅读12分钟

.NETCORE 容器源码讲解

/**
* 这里奉上基本使用方法  
* 1. 定义接口和实现类 假定AService实现了IAService,且AService是需要被手动释放的(实现IDisposable),且依赖IBService(IBService就是一个普通的接口)
* 2. 创建容器实例,并添加IAService和IBService 
* 3. 使用容器实例创建子容器,并且获取IAService服务,调用其方法 
* 4. 释放容器和子容器 
* 
* 通过以上可以看出,使用容器的好处共有 
* 1. 管理对象之间的依赖IAService依赖IBService,我们只需要将IBService注入进容器即可 
* 2. 对象的控制权交由容器来管理,需要什么向容器中获取即可(对象的创建及销毁)
* 3. 统一配置及生命周期控制
*/

public interface IAService
{
    void Hello();
}

public class AService : IAService , IDisposable
{

    public AService(IBService bService)
    {
    }
    
    public void Hello()
    {
        Console.WriteLine("Hello AService");
    }
    
    public void Dispose()
    {
        Console.WriteLine("AService Dispose Invoke");
    }
}

public interface IBService
{
}

public class BService : IBService
{
    public BService()
    {
    }
}

//构建容器
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddScoped<IAService,AService>();
serviceCollection.AddScoped<IBService,BService>();
//配置校验参数 ValidateScopes 校验是否作用域服务在跟服务提供者上解析 ValidateOnBuild 在构建之初开始校验(做好获取服务的准备)  
var options = new ServiceProviderOptions() { ValidateScopes = true, ValidateOnBuild = true };
using var rootServiceProvider = serviceCollection.BuildServiceProvider(options);
//创建一个子服务
using var scope = rootServiceProvider.CreateScope();
var childServiceProvider = scope.ServiceProvider;
//获取一个服务及调用其方法
var aService = childServiceProvider.GetRequiredService<IAService>();
aService.Hello();
//程序结束 释放了容器 则会自动释放容器管理的所有对象  
/**
* 我们先来看看 IServiceCollection 的接口定义 
* 实现了IList<ServiceDescriptor> 其本质上就是一个 ServiceDescriptor 集合
*/
public interface IServiceCollection : IList<ServiceDescriptor>
{
}

/**
* 继续来看 ServiceDescriptor 的定义(删减版仅保留了核心字段) 本质上是一个DTO
* ServiceLifetime Lifetime 服务的生命周期 瞬时/单例/范围
* Type ServiceType { get; } 服务的抽象类型(也可以是实际类型) 使用这个类型到容器获取对象
* Type? ImplementationType { get; }  服务的实现类型(也就是实际获取到的对象类型)
* object? ImplementationInstance { get; }  服务实例对象,不常用 当这个字段包含值时 获取的服务为该对象 会忽略掉作用域 
* Func<IServiceProvider, object>? ImplementationFactory { get; } 获取服务的工厂方法
*/
public class ServiceDescriptor
{
    public ServiceLifetime Lifetime { get; }
    public Type ServiceType { get; }
    public Type? ImplementationType { get; }
    public object? ImplementationInstance { get; }
    public Func<IServiceProvider, object>? ImplementationFactory { get; }
}

/**
* 我们继续来看 IServiceCollection 的实现类 ServiceCollection 
* 可以看到其内部持有 List<ServiceDescriptor> _descriptors 字段用来保存 ServiceDescriptor 集合
* 可以看做是 List<ServiceDescriptor> 的静态代理 这样做的好处是可以封装些许List之外的逻辑
*/

public class ServiceCollection : 
    IServiceCollection,
    IList<ServiceDescriptor>,
    ICollection<ServiceDescriptor>,
    IEnumerable<ServiceDescriptor>,
    IEnumerable
  {
    private readonly List<ServiceDescriptor> _descriptors = new List<ServiceDescriptor>();
    public int Count => this._descriptors.Count;
    public bool IsReadOnly => false;
    public ServiceDescriptor this[int index]
    {
      get => this._descriptors[index];
      set => this._descriptors[index] = value;
    }
    public void Clear() => this._descriptors.Clear();
    public bool Contains(ServiceDescriptor item) => this._descriptors.Contains(item);
    public void CopyTo(ServiceDescriptor[] array, int arrayIndex) => this._descriptors.CopyTo(array, arrayIndex);
    public bool Remove(ServiceDescriptor item) => this._descriptors.Remove(item);
    public IEnumerator<ServiceDescriptor> GetEnumerator() => (IEnumerator<ServiceDescriptor>) this._descriptors.GetEnumerator();
    void ICollection<ServiceDescriptor>.Add(ServiceDescriptor item) => this._descriptors.Add(item);
    IEnumerator IEnumerable.GetEnumerator() => (IEnumerator) this.GetEnumerator();
    public int IndexOf(ServiceDescriptor item) => this._descriptors.IndexOf(item);
    public void Insert(int index, ServiceDescriptor item) => this._descriptors.Insert(index, item);
    public void RemoveAt(int index) => this._descriptors.RemoveAt(index);
  }
/**
* 我们在来看看 IServiceCollection.AddScoped() 方法的实现逻辑
* 其本质是调用 IServiceCollection.Add()方法 只是在内部帮你实例化了 ServiceDescriptor 对象 
* AddSingleton AddTransient 同理 
* TryAddAddScoped TryAddSingleton TryAddTransient 在其上进行了判断该服务是否已在集合中 如果不在则添加,存在则丢弃 
*/
    
    //调用重载方法 推测出 serviceType 和 implementationType
    public static IServiceCollection AddScoped<TService,TImplementation>(
      this IServiceCollection services)
      where TService : class
      where TImplementation : class, TService
    {
      return services.AddScoped(typeof (TService), typeof (TImplementation));
    }
    
    //调用 ServiceCollectionServiceExtensions.Add 并且将服务声明为 ServiceLifetime.Scoped
    public static IServiceCollection AddScoped(
      this IServiceCollection services,
      Type serviceType,
      Type implementationType)
    {
      return ServiceCollectionServiceExtensions.Add(services, serviceType, implementationType, ServiceLifetime.Scoped);
    }
    
    //构造 ServiceDescriptor 本质是调用其Add方法添加到集合中
    private static IServiceCollection Add(
      IServiceCollection collection,
      Type serviceType,
      [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType,
      ServiceLifetime lifetime)
    {
      ServiceDescriptor serviceDescriptor = new ServiceDescriptor(serviceType, implementationType, lifetime);
      collection.Add(serviceDescriptor);
      return collection;
    }

/**
* 接下来来看看 IServiceCollection.BuildServiceProvider() 扩展方法
* 初始化然后返回 ServiceProvider 传入了 ICollection<ServiceDescriptor> 和 ServiceProviderOptions 校验
*/

    public static ServiceProvider BuildServiceProvider(
      this IServiceCollection services,
      ServiceProviderOptions options)
    {
      if (services == null)
        throw new ArgumentNullException(nameof (services));
      return options != null ? new ServiceProvider((ICollection<ServiceDescriptor>) services, options) : throw new ArgumentNullException(nameof (options));
    }
/**
* 我们先看看 ServiceProvider 构造函数
* 说白了就是为一些字段进行赋值 并且校验(如果配置了的话)
*/

internal ServiceProvider(
      ICollection<ServiceDescriptor> serviceDescriptors,
      ServiceProviderOptions options)
    {
      //ServiceProviderEngineScope 实现了 IServiceProvider 和 IServiceScope 也表示为容器对象(负责存储需要释放的容器对象,其核心方法都是调用This进行转发),在这里还表示为跟容器对象,后续在创建子容器的时候也会使用到 
	  //在后续会有专门的篇幅讲解(重点对象)
      this.Root = new ServiceProviderEngineScope(this, true);
      //在Core环境下始终是 DynamicServiceProviderEngine 实现  
      this._engine = this.GetEngine();
	  //委托赋值(这是获取服务的重点入口)
      this._createServiceAccessor = this.CreateServiceAccessor;
      //一级缓存 Type=>Func<ServiceProviderEngineScope, object>
      this._realizedServices = new ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>>();
	  //CallSiteFactory 负责获取 ServiceCallSite   
      this.CallSiteFactory = new CallSiteFactory(serviceDescriptors);
      //提前向 CallSiteFactory 注入 IServiceProvider IServiceScopeFactory IServiceProviderIsService 使得获取的时候可以取到相关的 ServiceCallSite
      //重点,具体会在后面篇幅中进行详细讲解   
      this.CallSiteFactory.Add(typeof (IServiceProvider), (ServiceCallSite) new ServiceProviderCallSite());
      this.CallSiteFactory.Add(typeof (IServiceScopeFactory), (ServiceCallSite) new ConstantCallSite(typeof (IServiceScopeFactory), (object) this.Root));
      this.CallSiteFactory.Add(typeof (IServiceProviderIsService), (ServiceCallSite) new ConstantCallSite(typeof (IServiceProviderIsService), (object) this.CallSiteFactory));
      //。。。。。。校验相关 篇幅有限 删除
    }
/**
* 首先来看看 IServiceProvider.CreateScope() 扩展方法 
* 创建一个子容器 在一个子容器内Scope作用域的服务实例是唯一的 
*/

//获取 IServiceScopeFactory 服务实例 ,调用其 CreateScope() 方法
//在ServiceProvider构造函数中 我们向 CallSiteFactory 中添加了 IServiceScopeFactory 实例对象为 ServiceProvider.Root
//也就是说这里获取到的服务实例对象为 ServiceProvider.Root (这里先不用管为什么获取到的是该对象,后面篇幅会讲解详细CallSiteFactory) 
public static IServiceScope CreateScope(this IServiceProvider provider)
{
    return provider.GetRequiredService<IServiceScopeFactory>().CreateScope();
}

//ServiceProviderEngineScope.CreateScope() 方法 其实就是在调用 ServiceProvider.CreateScop();
public IServiceScope CreateScope() => RootProvider.CreateScope();

//初始化并返回 new ServiceProviderEngineScope(this, isRootScope: false); 
internal IServiceScope CreateScope()
{
    if (_disposed) ThrowHelper.ThrowObjectDisposedException();
    return new ServiceProviderEngineScope(this, isRootScope: false);
}

/**
* 在来看一下 ServiceProviderEngineScope 源码 
* 注意该类 实现了 IServiceScope 和 IServiceProvider 表示为容器可获取服务对象和创建子容器 
* 其 GetService 方法仅仅是调用 RootServiceProvider.GetService() 但是传入的参数是 this = new ServiceProviderEngineScope(ServiceProvider RootProvider,false)
* 其 CreateScope 方法仅仅是调用 RootServiceProvider.CreateScope()
* 其 CaptureDisposable 创建好服务对象之后需要回调此方法
*    如果是跟容器 则缓存(需要实现IDispose且不能是This对象)单例|瞬时|范围
*    如果是子容器 则缓存(需要实现IDispose且不能是This对象)瞬时|范围  
* 其 Dispose() 表示为释放对象(会释放被容器管理的所有对象)
*/

internal sealed class ServiceProviderEngineScope : 
    IServiceScope,
    IDisposable,
    IServiceProvider,
    IAsyncDisposable,
    IServiceScopeFactory
  {
    //是否 Dispose 
    private bool _disposed;
    //需要释放的对象列表 如果是Root存储所有实现了IDispose的服务实例 如果是子Scope则仅存储范围和瞬时生命周期的服务实例 
    //在调用其 Dispose 方法的时候会循环其所有对象进行释放 这是重点(服务实例的释放交由容器来管理 开发者管理容器即可) 
    private List<object> _disposables;
    internal IList<object> Disposables => (IList<object>) this._disposables ?? (IList<object>) Array.Empty<object>();
    //赋值相关 简单初始化删除 。。。。。。
    public ServiceProviderEngineScope(ServiceProvider provider, bool isRootScope);
    //缓存 Scope 生命周期的服务实例
    internal Dictionary<ServiceCacheKey, object> ResolvedServices { get; }
    //并发锁 避免多次Dispose
    internal object Sync => (object) this.ResolvedServices;
    //是否是 Root 
    public bool IsRootScope { get; }
    //跟 ServiceProvider
    internal ServiceProvider RootProvider { get; }
    //调用其 ServiceProvider.GetService() 方法 
    public object GetService(Type serviceType)
    {
      if (this._disposed) ThrowHelper.ThrowObjectDisposedException();
      return this.RootProvider.GetService(serviceType, this);
    }

    public IServiceProvider ServiceProvider => (IServiceProvider) this;
    public IServiceScope CreateScope() => this.RootProvider.CreateScope();
    //资源释放 释放容器管理的所有对象 
    public void Dispose()
    {
      //其实就是返回 Disposables 数组 额外添加了判断如果已经被释放了则返回NULL 
      List<object> objectList = this.BeginDispose();
      if (objectList == null) return;
      for (int index = objectList.Count - 1; index >= 0; --index) {disposable.Dispose();}
    }

    internal object CaptureDisposable(object service)
        {
            //自身节点 | 未实现 IDisposable |  未实现 IAsyncDisposable 直接返回 服务实例对象 
            if (ReferenceEquals(this, service) || !(service is IDisposable || service is IAsyncDisposable)) return service;
            //删剪版。。。。。。
            lock (Sync){
                _disposables ??= new List<object>();
                _disposables.Add(service);
            }
            return service;
        }
  }
/**
* 在来看看其核心方法 ServiceProvider.GetService() 方法 
*/

//调用重载方法 传入了对象 this.Root = new ServiceProviderEngineScope(this, true);
public object GetService(Type serviceType) => this.GetService(serviceType, this.Root);

//_realizedServices getOrAdd 相当于一层缓存 如果存在直接返回 不存在调用 this._createServiceAccessor = this.CreateServiceAccessor 方法 
//Func<ServiceProviderEngineScope, object> 调用传入 ServiceProviderEngineScope 返回服务实例对象 
//所以核心逻辑在哪里? CreateServiceAccessor 返回的委托即 ServiceProviderEngineScope 相互配合 
//这里先不看 CreateServiceAccessor 逻辑代码 咱们先向下看看 ServiceProviderEngineScope 对象 
internal object GetService(
      Type serviceType,
      ServiceProviderEngineScope serviceProviderEngineScope)
{
    //释放了直接抛出错误 
    if (_disposed) ThrowHelper.ThrowObjectDisposedException();
	//缓存中包含则从缓存中获取 不包含则调用 _createServiceAccessor = CreateServiceAccessor
	//获取服务的重点核心入口
    Func<ServiceProviderEngineScope, object> realizedService = _realizedServices.GetOrAdd(serviceType, _createServiceAccessor);
	//校验相关(如果开启了则判断是否在跟上获取作用域的服务)
    OnResolve(serviceType, serviceProviderEngineScope);
    //调用获取服务实例对象 
    var result = realizedService.Invoke(serviceProviderEngineScope);
    return result;
}

//重点核心逻辑 返回的委托调用后返回服务实例对象 
private Func<ServiceProviderEngineScope, object> CreateServiceAccessor(Type serviceType)
{
    //CallSiteChain 防止循环依赖的解决对象 根据 ServiceCallSite 创建实例对象  
    //在下面会有单独的篇幅讲解(重点对象)
    ServiceCallSite callSite = CallSiteFactory.GetCallSite(serviceType, new CallSiteChain());
    if (callSite != null)
    {
        //校验相关
        OnCreate(callSite);
        
        //如果是单例模式 
        if (callSite.Cache.Location == CallSiteResultCacheLocation.Root)
        {
            //直接获取实例对象 封装在委托中 这里调用传入了Root
			//会有单独的篇幅讲解(重点对象)
            object value = CallSiteRuntimeResolver.Instance.Resolve(callSite, Root);
            //注意这里并未使用委托传入的 scope  单例服务使用RootServiceProvider创建即可
            return scope => value;
        }
        //_engine = new DynamicServiceProviderEngine() 
        //其内部返回的委托中 也是调用的 CallSiteRuntimeResolver.Instance.Resolve(callSite, scope);
        return _engine.RealizeService(callSite);
    }
    //没有注册该类 返回NULL 
    return _ => null;
}


/**
* CallSiteFactory 主要负责创建 ServiceCallSite
* ServiceCallSite 是一个抽象类 本质上也是一个DTO  
*/

internal abstract class ServiceCallSite
    {
        //服务类型
        public abstract Type ServiceType { get; }
        //服务实现类型
        public abstract Type ImplementationType { get; }
        //ServiceCallSite 类型 IEnumerable | Constant | Factory |  Constructor | ServiceProvider 。。。。。。。 
        public abstract CallSiteKind Kind { get; }
        //生命周期 服务类型 索引(多个实现中的索引)
        public ResultCache Cache { get; }
        //实例对象 单例/范围 使用到 
        public object Value { get; set; }
    }

internal sealed class CallSiteFactory : IServiceProviderIsService{
    //添加到私有字段 _callSiteCache 中 在获取 ServiceCallSite 的时候 会先判断 _callSiteCache 中是否存在 如果存在则直接返回 
    //在ServiceProvider构造函数中 往里面添加了 IServiceProvider IServiceScopeFactory IServiceProviderIsService  
    public void Add(Type type, ServiceCallSite serviceCallSite)
        {
            _callSiteCache[new ServiceCacheKey(type, DefaultSlot)] = serviceCallSite;
        }
    
    public CallSiteFactory(ICollection<ServiceDescriptor> descriptors)
        {
            _stackGuard = new StackGuard();
            //新建了一个ServiceDescriptor集合 避免在容器运行的过程中向IServiceCollection中添加元素 
            _descriptors = new ServiceDescriptor[descriptors.Count];
            descriptors.CopyTo(_descriptors, 0);
            //循环遍历 _descriptors 字段 向 Dictionary<Type, ServiceDescriptorCacheItem>() _descriptorLookup  中添加元素 
            //ServiceDescriptorCacheItem 本质上是 ServiceDescriptor 的集合 一个服务类型可能有多个实现类注入 支持获取IEnumerable<T> 多个服务
            Populate();
        }
        
        private void Populate()
        {
            foreach (ServiceDescriptor descriptor in _descriptors)
            {
                Type serviceType = descriptor.ServiceType;
                // 。。。。。。。校验代码删除
                Type cacheKey = serviceType;
                _descriptorLookup.TryGetValue(cacheKey, out ServiceDescriptorCacheItem cacheItem);
                _descriptorLookup[cacheKey] = cacheItem.Add(descriptor);
            }
        }
        
        //判断是否有通过 Add 添加进来的 ServiceCallSite 
				//如果没有则调用 CreateCallSite()
        internal ServiceCallSite GetCallSite(Type serviceType, CallSiteChain callSiteChain) =>
            _callSiteCache.TryGetValue(new ServiceCacheKey(serviceType, DefaultSlot), out ServiceCallSite site) ? site :
            CreateCallSite(serviceType, callSiteChain);
            
        private ServiceCallSite CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
        {
            //获取锁 每个服务类型分别有一个锁 这样粒度细 
            var callsiteLock = _callSiteLocks.GetOrAdd(serviceType, static _ => new object());

            lock (callsiteLock)
            {
                //检查是否循环引用了
                callSiteChain.CheckCircularDependency(serviceType);
                
                ServiceCallSite callSite = 
                                            //根据服务类型和循环引用对象创建 常规的方式 篇幅有限这里仅向下分析TryCreateExact
                                            TryCreateExact(serviceType, callSiteChain) ??
                                            //范型服务类型 ILogger<T> 
                                            TryCreateOpenGeneric(serviceType, callSiteChain) ??
                                            //获取一个相同服务类型的集合实例 
                                            TryCreateEnumerable(serviceType, callSiteChain);
                return callSite;
            }
        }
        
        private ServiceCallSite TryCreateExact(Type serviceType, CallSiteChain callSiteChain)
        {
            //判断是否存在这个服务类型 
            if (_descriptorLookup.TryGetValue(serviceType, out ServiceDescriptorCacheItem descriptor))
            {
                //如果存在 则进行创建 ServiceCallSite
                return TryCreateExact(descriptor.Last, serviceType, callSiteChain, DefaultSlot);
            }

            return null;
        }
        
        private ServiceCallSite TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, int slot)
        {
            if (serviceType == descriptor.ServiceType)
            {
                ServiceCacheKey callSiteKey = new ServiceCacheKey(serviceType, slot);
                //判断一下缓存是否存在 
                if (_callSiteCache.TryGetValue(callSiteKey, out ServiceCallSite serviceCallSite)) 
                    return serviceCallSite;

                ServiceCallSite callSite;
                
                //CallSiteResultCacheLocation Location descriptor.Lifetime 是相对应的  
                var lifetime = new ResultCache(descriptor.Lifetime, serviceType, slot);
                
                //如果这个字段不为空 也就是在IServiceCollection.Add() 给ImplementationInstance(服务实例对象)参数赋值的话 则直接返回 ConstantCallSite
                //后续会根据 callSite.Kind CallSiteKind 创建的时候自动返回该  descriptor.ImplementationInstance
                if (descriptor.ImplementationInstance != null)
                {
                    callSite = new ConstantCallSite(descriptor.ServiceType, descriptor.ImplementationInstance);
                }
                //Factory模式 并没有传递 callSiteChain 
                //这里会有死循环的问题 A=>B B=>A (provider)=>{new B(provider.GetService<A>())} 
                else if (descriptor.ImplementationFactory != null)
                {
                    callSite = new FactoryCallSite(lifetime, descriptor.ServiceType, descriptor.ImplementationFactory);
                }
                //构造函数注入 会遍历所有构造参数 递归构造 ServiceCallSite 存储到内部字段集合中
                else if (descriptor.ImplementationType != null)
                {
                    //没有公参构造函数的话 直接抛错
                    //一个构造函数 并且遍历所有构造参数 递归生成 ServiceCallSite
                    //多个构造参数 按参数个数从高到低排序 选取第一个可被容器构造的的构造函数 
                    callSite = CreateConstructorCallSite(lifetime, descriptor.ServiceType, descriptor.ImplementationType, callSiteChain);
                }
                else
                {
                    throw new InvalidOperationException(SR.InvalidServiceDescriptor);
                }
                
                //写入了缓存中 
                return _callSiteCache[callSiteKey] = callSite;
            }

            return null;
        }
/**
* 最后我们来看看 CallSiteRuntimeResolver 其负责创建服务实例 
* 核心方法 Resolve() 创建服务实例 
*/
internal sealed class CallSiteRuntimeResolver : CallSiteVisitor<RuntimeResolverContext, object>
    {
        public static CallSiteRuntimeResolver Instance { get; } = new();

        public object Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
        {
            //缓存中包含 直接返回 
            if (scope.IsRootScope && callSite.Value is object cached)
            {
                return cached;
            }
            
            //创建服务实例 父类实现 
            return VisitCallSite(callSite, new RuntimeResolverContext
            {
                Scope = scope
            });
        }
        
        //创建服务实例
        protected virtual TResult VisitCallSite(ServiceCallSite callSite, TArgument argument)
        {
            switch (callSite.Cache.Location)
            {
                //单例生命周期
                case CallSiteResultCacheLocation.Root:
                    return VisitRootCache(callSite, argument);
                //范围生命周期
                case CallSiteResultCacheLocation.Scope:
                    return VisitScopeCache(callSite, argument);
                //瞬时生命周期 如果服务实例需要帮忙释放则帮助 但是并不缓存,这里不要被名称给误导了
                case CallSiteResultCacheLocation.Dispose:
                    return VisitDisposeCache(callSite, argument);
                //未知生命周期(按道理是不会出现的)
                case CallSiteResultCacheLocation.None:
                    return VisitNoCache(callSite, argument);
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
        
        //创建服务实例 在Root 且会缓存到
        protected override object VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
        {
            //缓存中是否包含 
            if (callSite.Value is object value) return value;

            ServiceProviderEngineScope serviceProviderEngine = context.Scope.RootProvider.Root;

            lock (callSite)
            {
                if (callSite.Value is object resolved) return resolved;
                //创建实例对象 
                resolved = VisitCallSiteMain(callSite, new RuntimeResolverContext
                {
                    Scope = serviceProviderEngine,
                    AcquiredLocks = context.AcquiredLocks | RuntimeResolverLock.Root
                });
                //如果需要容器帮忙释放
                serviceProviderEngine.CaptureDisposable(resolved);
                //缓存起来
                callSite.Value = resolved;
                return resolved;
            }
        }
        
        protected override object VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
        {
            //如果是跟节点(跟节点获取范围的服务是不被允许的,但是在没有加校验的情况下是可被执行的) 则提升作用域为单例
            //非跟节点 缓存在 serviceProviderEngineScope 中 
            return context.Scope.IsRootScope ?
                VisitRootCache(callSite, context) :
                VisitCache(callSite, context, context.Scope, RuntimeResolverLock.Scope);
        }

        protected override object VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
        {
            return context.Scope.CaptureDisposable(VisitCallSiteMain(transientCallSite, context));
        }
        、
        //会判断在一个IServiceScope中 是否有被缓存 如果被缓存 直接使用 未缓存 则创建服务实例 
        //用作Scope生命周期
        private object VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
        {
            bool lockTaken = false;
            object sync = serviceProviderEngine.Sync;
            //获取缓存对象 在 Scope 中  
            Dictionary<ServiceCacheKey, object> resolvedServices = serviceProviderEngine.ResolvedServices;
            if ((context.AcquiredLocks & lockType) == 0)
            {
                Monitor.Enter(sync, ref lockTaken);
            }

            try
            {
                //尝试获取值 
                if (resolvedServices.TryGetValue(callSite.Cache.Key, out object resolved))
                {
                    return resolved;
                }

                //创建服务实例对象
                resolved = VisitCallSiteMain(callSite, new RuntimeResolverContext
                {
                    Scope = serviceProviderEngine,
                    AcquiredLocks = context.AcquiredLocks | lockType
                });
                
                //释放相关 
                serviceProviderEngine.CaptureDisposable(resolved);
                //缓存起来 
                resolvedServices.Add(callSite.Cache.Key, resolved);
                return resolved;
            }
            finally
            {
            }
        }
        
        //核心创建服务实例
        protected virtual TResult VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
        {
            switch (callSite.Kind)
            {
                //工厂模式 services.AddScope<IAService>((provider)=>new AService())
                case CallSiteKind.Factory:
                    return VisitFactory((FactoryCallSite)callSite, argument);
                //provider.GetService<IEnumerable<IAService>>()
                case  CallSiteKind.IEnumerable:
                    return VisitIEnumerable((IEnumerableCallSite)callSite, argument);
                //构造函数创建服务实例 services.AddScope<IAService,AService>();
                case CallSiteKind.Constructor:
                    return VisitConstructor((ConstructorCallSite)callSite, argument);
                //常量 IServiceProvider IServiceScopeFactory  IServiceProviderIsService 或者是在自定义注入向 ServiceDescriptor.ImplementationInstance 赋值
                case CallSiteKind.Constant:
                    return VisitConstant((ConstantCallSite)callSite, argument);
                //这里是获取IServiceProvider对象
                case CallSiteKind.ServiceProvider:
                    return VisitServiceProvider((ServiceProviderCallSite)callSite, argument);
                //其他则报错
                default:
                    throw new NotSupportedException(SR.Format(SR.CallSiteTypeNotSupported, callSite.GetType()));
            }
        }

        protected override object VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
        {
            object[] parameterValues;
            if (constructorCallSite.ParameterCallSites.Length == 0)
            {
                parameterValues = Array.Empty<object>();
            }
            else
            {
                parameterValues = new object[constructorCallSite.ParameterCallSites.Length];
                for (int index = 0; index < parameterValues.Length; index++)
                {
                    parameterValues[index] = VisitCallSite(constructorCallSite.ParameterCallSites[index], context);
                }
            }
            
            //反射构造对象
            return constructorCallSite.ConstructorInfo.Invoke(BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameterValues, culture: null);
        }

        protected override object VisitConstant(ConstantCallSite constantCallSite, RuntimeResolverContext context)
        {
            return constantCallSite.DefaultValue;
        }

        protected override object VisitServiceProvider(ServiceProviderCallSite serviceProviderCallSite, RuntimeResolverContext context)
        {
            return context.Scope;
        }

        protected override object VisitIEnumerable(IEnumerableCallSite enumerableCallSite, RuntimeResolverContext context)
        {
            var array = Array.CreateInstance(
                enumerableCallSite.ItemType,
                enumerableCallSite.ServiceCallSites.Length);

            for (int index = 0; index < enumerableCallSite.ServiceCallSites.Length; index++)
            {
                object value = VisitCallSite(enumerableCallSite.ServiceCallSites[index], context);
                array.SetValue(value, index);
            }
            return array;
        }

        protected override object VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
        {
            return factoryCallSite.Factory(context.Scope);
        }
    }