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

这里我们看下CallSiteFactory.GetCallSite方法,先来说一下这个方法是做啥的 。我们要获取某个类型的实例(可以理解为我们演示示例里的Person类),但是我们注册类相关的信息的时候(比如上面的services.AddScoped<Person>(provider => new() { Id = 1, Name = "yi念之间", Sex = "Man" }))涉及到几种方式,比如AddScoped<T>Add<T>(Func<IServiceProvider,object>),我们需要知道创建类型实例的时候使用哪种方式(比如我们的Person是使用委托的这种方式),ServiceCallSite正是存储的类型和如何创建这个类型的工厂相关的信息 。我们来看一下GetCallSite方法的核心操作[点击查看源码]
private readonly ConcurrentDictionary<ServiceCacheKey, ServiceCallSite> _callSiteCache = new ConcurrentDictionary<ServiceCacheKey, ServiceCallSite>();private ServiceCallSite TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, int slot){    if (serviceType == descriptor.ServiceType)    {        //要获取的类型会被包装成ServiceCacheKey        ServiceCacheKey callSiteKey = new ServiceCacheKey(serviceType, slot);        //在缓存中获取ServiceCallSite实例,可以理解为设计模式中的享元模式        if (_callSiteCache.TryGetValue(callSiteKey, out ServiceCallSite serviceCallSite))        {            return serviceCallSite;        }        ServiceCallSite callSite;        //根据ServiceDescriptor.Lifetime包装ResultCache        var lifetime = new ResultCache(descriptor.Lifetime, serviceType, slot);        //ServiceDescriptor就是我们添加到IServiceCollection的最终形式        //我们注册服务的时候本质就是在IServiceCollection里添加ServiceDescriptor实例        //AddScope<T>()这种形式        if (descriptor.ImplementationInstance != null)        {            callSite = new ConstantCallSite(descriptor.ServiceType, descriptor.ImplementationInstance);        }        //AddScope(Func<IServiceProvider,object>)形式        else if (descriptor.ImplementationFactory != null)        {            callSite = new FactoryCallSite(lifetime, descriptor.ServiceType, descriptor.ImplementationFactory);        }        //AddScope<T,TImpl>()形式        else if (descriptor.ImplementationType != null)        {            callSite = CreateConstructorCallSite(lifetime, descriptor.ServiceType, descriptor.ImplementationType, callSiteChain);        }        else        {            throw new InvalidOperationException(SR.InvalidServiceDescriptor);        }        //将创建的ServiceCallSite缓存起来        return _callSiteCache[callSiteKey] = callSite;    }    return null;}而解析ServiceCallSite实例的方法RealizeService(ServiceCallSite)则是在ServiceProviderEngine类中,看一下相关实现[点击查看源码]
 public override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite){    int callCount = 0;    return scope =>    {        //核心代码是Resolve方法,这里的scope则是ServiceProviderEngineScope        //即我们上面通过CreateScope()创建的实例        var result = CallSiteRuntimeResolver.Instance.Resolve(callSite, scope);        if (Interlocked.Increment(ref callCount) == 2)        {            _ = ThreadPool.UnsafeQueueUserWorkItem(_ =>            {                try                {                    _serviceProvider.ReplaceServiceAccessor(callSite, base.RealizeService(callSite));                }                catch (Exception ex)                {                   //省略掉非核心代码                }            },            null);        }        return result;    };}

推荐阅读