• DependencyInjection源码解读之ServiceProvider


    var services = new ServiceCollection();
    var _serviceProvider = services.BuildServiceProvider();
    serviceScope = _serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope()
    var internalServiceProvider = serviceScope.ServiceProvider;
    上面几行代码内部发生了什么?
     
    要弄清这个过程,我们先得了解一下ServiceProvider创建过程.
    ServiceProvider 有两个构造方法,一个用来创建Root ServiceProvider ,和个用来创建 Not Root ServiceProvider。
    为了方便称呼,我们把它们称为 RootServiceProvider和 InternalServiceProvider 
     
    构造方法一,用来创建一个rootServiceProvider,Root属性指向自己。
    internal ServiceProvider(IEnumerable<ServiceDescriptor> serviceDescriptors, ServiceProviderOptions options)
    {
        Root = this;
    
        if (options.ValidateScopes)
        {
            _callSiteValidator = new CallSiteValidator();
        }
    
        _table = new ServiceTable(serviceDescriptors);
    
        _table.Add(typeof(IServiceProvider), new ServiceProviderService());
        _table.Add(typeof(IServiceScopeFactory), new ServiceScopeService());
        _table.Add(typeof(IEnumerable<>), new OpenIEnumerableService(_table));
    }
     
    构造方法二,用来创建一个InternalServiceProvider,Root属性指向传入的ServiceProvider(居然可以单性繁殖)。
    internal ServiceProvider(ServiceProvider parent)
    {
        Root = parent.Root;
        _table = parent._table;
        _callSiteValidator = parent._callSiteValidator;
    }
    注意:RootServiceProvider 和 InternalServiceProvider 并没有什么本质上的不同,但还是有两点区别:
    1.RootServiceProvider 的 Root 属性指向的是自己,而 InternalServiceProvider 指向的是 RootServiceProvider
    2.RootServiceProvider 创建时会创建一个新的ServiceTable,并注册三个默认的依赖服务。
    _table = new ServiceTable(serviceDescriptors);
    //注入默认的依赖注入,这样才能在使用 _serviceProvider.GetRequiredService<IServiceScopeFactory>() 或在创建对象时为构造方法中的IServiceProvider 注入实例。
    _table.Add(typeof(IServiceProvider), new ServiceProviderService()); 
    _table.Add(typeof(IServiceScopeFactory), new ServiceScopeService());
    _table.Add(typeof(IEnumerable<>), new OpenIEnumerableService(_table));
    回到最上面的几行代码,跟据参数可以看到。
    BuildServiceProvider() 创建的是 RootServiceProvider, serviceScope.ServiceProvider 创建的是 InternalServiceProvider
    具体过程为:
    // BuildServiceProvider() 是扩展方法,有三个重载
    //最终实现方法定义:this IServiceCollection services, ServiceProviderOptions options
    //其中services是当前扩展的IServiceCollection,options是一些可选扩展选项
    BuildServiceProvider() == new ServiceProvider(services, options); 
    
    _serviceProvider.GetRequiredService<IServiceScopeFactory>();
    //这一句获取一个ServiceScopeFactory实例,IServiceScopeFactory我们上面说过了,创建RootServiceProvider时内部注册的。
    
    // CreateScope() 
    // CreateScope()是在IServiceScopeFactory接口内定义,ServiceScopeFactory类的实现为:
    //return new ServiceScope(new ServiceProvider(_provider)); 
    //其中_provider参数类型为ServiceProvider,是ServiceScopeFactory类的一个字段,其值来自构造方法注入
    CreateScope() == new ServiceScope(new ServiceProvider(_provider));
    需要注意的是,它们所在方法接收的参数 IServiceCollection 还是 ServiceProvider
    如果接收的是IServiceCollection,是可以直接转化为 IEnumerable<ServiceDescriptor>的。因为IServiceCollection 是一个继承自 IList<ServiceDescriptor>的空接口。
    所以BuildServiceProvider()所在方法接收的参数 IServiceCollection services 直接转化为构造方法一所需要的 IEnumerable<ServiceDescriptor> serviceDescriptors 
  • 相关阅读:
    电脑发朋友圈神器?不是严格意义上的
    微信公众平台投票功能升级 可多渠道发布投票
    多客服功能终于也向所有微信认证的订阅号开放了
    微信电脑版-微信for windows客户端发布
    微信朋友圈广告的赢家是他们
    微信公众平台原创声明功能公测 自媒体原创保护的福音
    微信公众平台数据接口正式对所有认证公众号开放
    壕,微信6.1版发微信红包更方便了,我们去喝杯茶吧
    微信公开课发布微信官方教程:教你用好微信JS-SDK接口
    微信公众平台开放JS-SDK(微信内网页开发工具包)
  • 原文地址:https://www.cnblogs.com/weapon/p/9126831.html
Copyright © 2020-2023  润新知