asp.net core的DI框架思考以及服務實例的獲取方式總結


轉載請注明出處: https://home.cnblogs.com/u/zhiyong-ITNote/

整個asp.net core管道從WebHostBuilder到WebHost到后續請求的類中,都是使用一個ServicesCollection。WebHostBuilder類中注冊的服務,以及后續用戶在Startup類的ConfigureServices方法中注入的服務都是在這個集成在這個ServicesCollection中。
根ServiceProvider: WebHost類中的屬性Services返回的ServiceProvider

private IServiceProvider _applicationServices;
public IServiceProvider Services
{
get
{
return _applicationServices;
}
}
View Code

它的實例化是通過IServicesCollection接口的拓展方法BuilderServiceProvider()實例化出來的。此時的實例化也是基於該ServicesCollection中注冊的服務。它的生命周期是應用程序從創建到結束的期間。也就是整個aspnet core整個管道的生命周期。asp.net core的DI框架中服務的注冊和服務實例化就是從這里開始的,貫徹到整個管道中....
每次請求所使用的ServiceProvider:
該ServiceProvider的生命周期在asp.net core中的定義是scope,即服務范圍——其實就是每一次的web請求。這也是aspnet core的DI框架三大生命周期中“Scope”含義:指的是針對每個HTTP請求的上下文,也就是服務范圍的生命周期與每個請求上下文綁定在一起。管道總是會創建一個新的ServiceProvider來提供處理每個請求所需的服務,並且這個ServiceProvider將在每次請求處理完成之后被自動回收掉。這樣一個ServiceProvider被創建之后直接保存到當前的HTTP上下文中,我們可以利用HttpContext如下所示的RequestServices屬性得到這個ServiceProvider。

根ServiceProvider的創建是在WebHostBuilder以及WebHost中,也就是aspnet core管道的創建初始時。終於aspnet core管道結束時。

非根ServiceProvider的創建是在一個中間件中,隨后寫入HttpContext中,也就是請求上下文。RequestServiceFeature類負責創建非根ServiceProvider:

private readonly IServiceScopeFactory _scopeFactory;
// 或者 private readonly IServiceProvider _serviceProvider;
_scope
= _scopeFactory.CreateScope();
// _scope = _serviceProvider.CreateScope(); _requestServices
= _scope.ServiceProvider;

是不是很眼熟?也就是我們平常創建一個新的scope的ServiceProvider的方式。對於IServiceScopeFactory接口,我之前描述過,請看《asp.net core 依賴注入實現全過程粗略剖析(3)》。如此就知道CreateScope方法的設計了。它就是為了創建一個特定范圍的ServiceProvider——初始的設計原則應該是為了在每個請求中實現一個特定的ServiceProvider。

如何創建一個ServiceProvider:
1、調用IServicesCollection接口的BuilderServiceProvider方法,該方法創建的是一個根ServiceProvider。
2、調用IServiceProvider接口的CreateScope隨后調用ServiceProvider屬性。該方法創建的是一個特定范圍的ServiceProvider。

總結一下aspnet core獲取注冊服務的實例如下:

IServiceProvider.CreateScope()
IServiceProvider.GetRequestService<IServiceScopeFactory>
HttpContext.RequestServices.GetService<>
IApplicationBuilder.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())

IWebHost.Services.GetService(typeof(IServiceScopeFactory))

疑惑:
這個疑惑我並沒有去寫代碼實踐,只是看了一篇博客自己思考了下。原博客<ASP.NET Core 新建線程中使用依賴注入的問題>.即使新開了線程,應該也是共用根ServiceProvider,根ServiceProvider應該不會在新線程中被銷毀了。

參考:

ASP.NET Core中如影隨形的”依賴注入”[上]: 從兩個不同的ServiceProvider說起

蔣金楠老師的博客,每次讀都有不同的收獲,如果你想要探索底層的原理,那么蔣老師的博客值得深看,多看

 

轉載請注明出處: https://home.cnblogs.com/u/zhiyong-ITNote/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM