zoukankan      html  css  js  c++  java
  • DOTNET CORE源码分析之IOC容器结果获取内容补充

      补充一下ServiceProvider的内容

      可能上一篇文章DOTNET CORE源码分析之IServiceProvider、ServiceProvider、IServiceProviderEngine、ServiceProviderEngine和ServiceProviderEngineScope 中还没有关联上ServiceProvider和ServiceCollection就直接通过GetService获取了值,这样不科学啊。其实是有关联的,请看一下上篇文章同样存在的一个代码段:

    internal ServiceProvider(
      IEnumerable<ServiceDescriptor> serviceDescriptors,
      ServiceProviderOptions options)
    {
      IServiceProviderEngineCallback callback = (IServiceProviderEngineCallback) null;
      if (options.ValidateScopes)
      {
    	callback = (IServiceProviderEngineCallback) this;
    	this._callSiteValidator = new CallSiteValidator();
      }
      switch (options.Mode)
      {
    	case ServiceProviderMode.Dynamic:
    	  this._engine = (IServiceProviderEngine) new DynamicServiceProviderEngine(serviceDescriptors, callback);
    	  break;
    	case ServiceProviderMode.Runtime:
    	  this._engine = (IServiceProviderEngine) new RuntimeServiceProviderEngine(serviceDescriptors, callback);
    	  break;
    	case ServiceProviderMode.Expressions:
    	  this._engine = (IServiceProviderEngine) new ExpressionsServiceProviderEngine(serviceDescriptors, callback);
    	  break;
    	case ServiceProviderMode.ILEmit:
    	  this._engine = (IServiceProviderEngine) new ILEmitServiceProviderEngine(serviceDescriptors, callback);
    	  break;
    	default:
    	  throw new NotSupportedException("Mode");
      }
    }
    

      是的在这个构造函数中第一个参数:IEnumerable<ServiceDescriptor> serviceDescriptors,这个就是ServiceCollection的对应参数,这样,保存了用户添加的注入信息就和ServiceProviderEngine关联上了,然后ServiceProviderEngine可以为调用方提供数据,换句话说,ServiceProvider不是直接提供数据响应,而是借用ServiceProviderEngine的子类来提供,并且提供了ServiceProviderMode中提供的几种方式。

      我们再看看ServiceProviderMode的构造函数,如下:

    protected ServiceProviderEngine(
      IEnumerable<ServiceDescriptor> serviceDescriptors,
      IServiceProviderEngineCallback callback)
    {
      this._createServiceAccessor = new Func<Type, Func<ServiceProviderEngineScope, object>>(this.CreateServiceAccessor);
      this._callback = callback;
      this.Root = new ServiceProviderEngineScope(this);
      this.RuntimeResolver = new CallSiteRuntimeResolver();
      this.CallSiteFactory = new CallSiteFactory(serviceDescriptors);
      this.CallSiteFactory.Add(typeof (IServiceProvider), (IServiceCallSite) new ServiceProviderCallSite());
      this.CallSiteFactory.Add(typeof (IServiceScopeFactory), (IServiceCallSite) new ServiceScopeFactoryCallSite());
      this.RealizedServices = new ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>>();
    }
    

      这个过程做了很多初始化,我们把关注点集中在这一句:this.CallSiteFactory = new CallSiteFactory(serviceDescriptors),这句把ServiceCollection传递给了CallSiteFactory。CallSiteFactory是创建ServiceCallSite的工厂,具体作用下如下代码中:

    private Func<ServiceProviderEngineScope, object> CreateServiceAccessor(
      Type serviceType)
    {
      IServiceCallSite callSite = this.CallSiteFactory.CreateCallSite(serviceType, new CallSiteChain());
      if (callSite == null)
    	return (Func<ServiceProviderEngineScope, object>) (_ => (object) null);
      this._callback?.OnCreate(callSite);
      return this.RealizeService(callSite);
    }
    

      这里的IServiceCallSite callSite = this.CallSiteFactory.CreateCallSite(serviceType, new CallSiteChain()) 函数CreateCallSite实现如下:

    internal IServiceCallSite CreateCallSite(
          Type serviceType,
          CallSiteChain callSiteChain)
    {
      lock (this._callSiteCache)
      {
    	IServiceCallSite serviceCallSite1;
    	if (this._callSiteCache.TryGetValue(serviceType, out serviceCallSite1))
    	  return serviceCallSite1;
    	IServiceCallSite serviceCallSite2;
    	try
    	{
    	  callSiteChain.CheckCircularDependency(serviceType);
    	  serviceCallSite2 = this.TryCreateExact(serviceType, callSiteChain) ?? this.TryCreateOpenGeneric(serviceType, callSiteChain) ?? this.TryCreateEnumerable(serviceType, callSiteChain);
    	}
    	finally
    	{
    	  callSiteChain.Remove(serviceType);
    	}
    	this._callSiteCache[serviceType] = serviceCallSite2;
    	return serviceCallSite2;
      }
    }
    

      其中this.TryCreateExact(serviceType, callSiteChain) ?? this.TryCreateOpenGeneric(serviceType, callSiteChain) ?? this.TryCreateEnumerable(serviceType, callSiteChain) 这个返回值是带有结果的ServiceCallSite,然后通过这个ServiceCallSite获取最终结果。

      接着介绍昨天没完成的内容

      昨天介绍到这个获取服务的函数,如下:

    protected override Func<ServiceProviderEngineScope, object> RealizeService(
      IServiceCallSite callSite)
    {
      int callCount = 0;
      return (Func<ServiceProviderEngineScope, object>) (scope =>
      {
        if (Interlocked.Increment(ref callCount) == 2)
          Task.Run<Func<ServiceProviderEngineScope, object>>((Func<Func<ServiceProviderEngineScope, object>>) (() => base.RealizeService(callSite)));
        return this.RuntimeResolver.Resolve(callSite, scope);
      });
    }
    

      关注点停留在this.RuntimeResolver.Resolve(callSite, scope),这个函数在调用过程的时候带有两个参数callSite和scope,callSite就是刚刚介绍的ServiceCallSite,Scope是ServiceProviderEngineScope。RuntimeResolver是CallSiteRuntimeResolver的实例,Resolve方法如下:

    public object Resolve(IServiceCallSite callSite, ServiceProviderEngineScope scope)
    {
      return this.VisitCallSite(callSite, scope);
    }
    

      其中VisitCallSite就是:

    protected virtual TResult VisitCallSite(IServiceCallSite callSite, TArgument argument)
    {
      switch (callSite.Kind)
      {
    	case CallSiteKind.Factory:
    	  return this.VisitFactory((FactoryCallSite) callSite, argument);
    	case CallSiteKind.Constructor:
    	  return this.VisitConstructor((ConstructorCallSite) callSite, argument);
    	case CallSiteKind.Constant:
    	  return this.VisitConstant((ConstantCallSite) callSite, argument);
    	case CallSiteKind.IEnumerable:
    	  return this.VisitIEnumerable((IEnumerableCallSite) callSite, argument);
    	case CallSiteKind.ServiceProvider:
    	  return this.VisitServiceProvider((ServiceProviderCallSite) callSite, argument);
    	case CallSiteKind.Scope:
    	  return this.VisitScoped((ScopedCallSite) callSite, argument);
    	case CallSiteKind.Transient:
    	  return this.VisitTransient((TransientCallSite) callSite, argument);
    	case CallSiteKind.CreateInstance:
    	  return this.VisitCreateInstance((CreateInstanceCallSite) callSite, argument);
    	case CallSiteKind.ServiceScopeFactory:
    	  return this.VisitServiceScopeFactory((ServiceScopeFactoryCallSite) callSite, argument);
    	case CallSiteKind.Singleton:
    	  return this.VisitSingleton((SingletonCallSite) callSite, argument);
    	default:
    	  throw new NotSupportedException(string.Format("Call site type {0} is not supported", (object) callSite.GetType()));
      }
    }
    

      然后:

    protected override object VisitConstant(
          ConstantCallSite constantCallSite,
          ServiceProviderEngineScope scope)
    {
        return constantCallSite.DefaultValue;
    }
    

      这个constantCallSite.Defaultvalue就是需要的返回结果了。

       上述的源码过程解析如下代码:

    IServiceCollection serviceCollection = new ServiceCollection();
    serviceCollection.AddSingleton(typeof(string), "lizizhang");
    ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
    string name = (string)serviceProvider.GetService(typeof(string));
    

      如果错误之处,请及时指正!

  • 相关阅读:
    解决This application failed to start because it could not find or load the Qt platform plugin "windows
    计算几何-凸包-toleft test
    Bit Operation妙解算法题
    带线表格据gt生成无线表格
    caffe的python接口提取resnet101某层特征
    camelot工具进行pdf表格解析重建
    python批量爬取文档
    IP被封检测地址
    驱动人生后门清除方案
    应用安全
  • 原文地址:https://www.cnblogs.com/lizhizhang/p/12546810.html
Copyright © 2011-2022 走看看