轉載請注明出處: 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; } }
它的實例化是通過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/