zoukankan      html  css  js  c++  java
  • DOTNET CORE源码分析之IServiceProvider、ServiceProvider、IServiceProviderEngine、ServiceProviderEngine和ServiceProviderEngineScope

      首先谈一下IServiceProvider

      IServiceProvider只提供给了一个根据类型获取对象的功能,试想一下IOC总得有一个找到对象,具体如下

    public interface IServiceProvider
    {
      object GetService(Type serviceType);
    }

      再谈一下ServiceProvider

      ServiceProvider实例化了IServiceProvider,也就是实现了GetService,用于获取容器中实际对象,但是它是借助于IServiceProviderEngine(这个接口稍后再介绍),具体如下:

    public object GetService(Type serviceType)
    {
      return this._engine.GetService(serviceType);
    }
    

      另外ServiceCollection中有一个方法BuildServiceProvider(存在于类ServiceCollectionContainerBuilderExtensions中),返回值对象类型就是ServiceProvider

    /// <summary>
    /// Extension methods for building a <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceProvider" /> from an <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
    /// </summary>
    public static class ServiceCollectionContainerBuilderExtensions
    {
    /// <summary>
    /// Creates a <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceProvider" /> containing services from the provided <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
    /// </summary>
    /// <param name="services">The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> containing service descriptors.</param>
    /// <returns>The <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceProvider" />.</returns>
    public static ServiceProvider BuildServiceProvider(
      this IServiceCollection services)
    {
      return services.BuildServiceProvider(ServiceProviderOptions.Default);
    }
    
    /// <summary>
    /// Creates a <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceProvider" /> containing services from the provided <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />
    /// optionaly enabling scope validation.
    /// </summary>
    /// <param name="services">The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> containing service descriptors.</param>
    /// <param name="validateScopes">
    /// <c>true</c> to perform check verifying that scoped services never gets resolved from root provider; otherwise <c>false</c>.
    /// </param>
    /// <returns>The <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceProvider" />.</returns>
    public static ServiceProvider BuildServiceProvider(
      this IServiceCollection services,
      bool validateScopes)
    {
      return services.BuildServiceProvider(new ServiceProviderOptions()
      {
    	ValidateScopes = validateScopes
      });
    }
    
    /// <summary>
    /// Creates a <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceProvider" /> containing services from the provided <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />
    /// optionaly enabling scope validation.
    /// </summary>
    /// <param name="services">The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" /> containing service descriptors.</param>
    /// <param name="options">
    /// Configures various service provider behaviors.
    /// </param>
    /// <returns>The <see cref="T:Microsoft.Extensions.DependencyInjection.ServiceProvider" />.</returns>
    public static ServiceProvider BuildServiceProvider(
      this IServiceCollection services,
      ServiceProviderOptions options)
    {
      if (services == null)
    	throw new ArgumentNullException(nameof (services));
      if (options == null)
    	throw new ArgumentNullException(nameof (options));
      return new ServiceProvider((IEnumerable<ServiceDescriptor>) services, options);
    }
    }
    

      必须要结合一下IServiceProviderEngine、ServiceProviderEngineServiceProviderEngineScope对象才能具体知道ServiceProvider是怎么获取IOC容器中的对象了

      在使用BuildServiceProvider的时候,最终会调用new ServiceProvider((IEnumerable<ServiceDescriptor>)services,options),然后就是调用如下函数:

    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");
      }
    }
    

      就是说最终还是根据ServiceProviderMode来判断需要实例化哪种ServiceProviderEngine,现在简单举例DynamicServiceProviderEngine。DynamicServiceProviderEngine最终还是继承ServiceProviderEngine,

    所以上面说的GetService其实就是调用了ServiceProviderEngine的GetService

    public object GetService(Type serviceType)
    {
      return this.GetService(serviceType, this.Root);
    }
    

      其中this.Root就是实例化的ServiceProviderScope。上面的this.GetService(serviceType,this.Root)会调用如下函数:

    internal object GetService(
      Type serviceType,
      ServiceProviderEngineScope serviceProviderEngineScope)
    {
      if (this._disposed)
    	ThrowHelper.ThrowObjectDisposedException();
      Func<ServiceProviderEngineScope, object> orAdd = this.RealizedServices.GetOrAdd(serviceType, this._createServiceAccessor);
      this._callback?.OnResolve(serviceType, (IServiceScope) serviceProviderEngineScope);
      ServiceProviderEngineScope providerEngineScope = serviceProviderEngineScope;
      return orAdd(providerEngineScope);
    }
    

      最终就是调用Func<ServiceProviderEngineScope, object> orAdd = this.RealizedServices.GetOrAdd(serviceType, this._createServiceAccessor);其中RealizedServices是ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>> RealizedServices { get; },this._createServiceAccessor是Func<ServiceProviderEngineScope, object>,通过这个委托根据ServiceProviderEngineScope获取最终的对象,也就是说,如果服务存在的话就从字典中获取,不存在就添加到队列上,并直接返回。另外在实例化ServiceProviderEngine的时候实例化了this._createServiceAccessor = new Func<Type, Func<ServiceProviderEngineScope, object>>(this.CreateServiceAccessor);其中CreateServiceAccessor是一个函数,定义如下:

    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);
    }
    

      就DynamicServiceProviderEngine而言,RealizeService的定义如下:

    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);
      });
    }
    

      RuntimeResolver是ServiceProviderEngine的一个属性。到此为止,IOC容器的数据就可以获取到了。下篇博客会继续说明this.RuntimeResover.Resolve下的事情。

  • 相关阅读:
    兼容ie8 rgba()用法 滤镜filter的用法
    解決BufferedReader读取UTF-8文件中文乱码
    基于JavaScript实现表单密码的隐藏和显示出来
    Java多线程学习(转载)
    使用java 程序创建格式为utf-8文件的方法(写入和读取json文件)
    java获取classpath文件路径空格转变成了转义字符%20的问题
    java中Class.getResource用法
    事务传播行为和特性
    事务隔离级别
    使用Condition循环依次打印123
  • 原文地址:https://www.cnblogs.com/lizhizhang/p/12542602.html
Copyright © 2011-2022 走看看