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 
相關文章
相關標籤/搜索