ASP.NET Core管道雖然在結(jié)構(gòu)組成上顯得非常簡單,但是在具體實現(xiàn)上卻涉及到太多的對象,所以我們在 “通過重建Hosting系統(tǒng)理解HTTP請求在ASP.NET Core管道中的處理流程”(上篇、中篇、下篇) 中圍繞著一個經(jīng)過極度簡化的模擬管道講述了真實管道構(gòu)建的方式以及處理HTTP請求的流程。在本系列 中,我們會還原構(gòu)建模擬管道時可以舍棄和改寫的部分,向讀者朋友們呈現(xiàn)一個真是的HTTP請求處理管道。 ASP.NET Core 的請求處理管道由一個服務(wù)器與一組有序排列的中間件構(gòu)成,前者僅僅完成請求監(jiān)聽、接收和響應(yīng)這些與底層網(wǎng)絡(luò)相關(guān)的工作,至于請求接收之后和響應(yīng)之前的所有工作都交給中間件來完成。ASP.NET Core的中間件通過一個類型Func<RequestDelegate, RequestDelegate>的委托對象來表示,而RequestDelegate也是一個委托,它代表一項請求處理任務(wù)。 [本文已經(jīng)同步到《ASP.NET Core框架揭秘》之中]
目錄
一、RequestDelegate
二、HttpContext
FeatureCollection
DefaultHttpContext
HttpContextFactory
三、ApplicationBuilder
ApplicationBuilderFactory
中間件類型
中間件類型的注冊
一、RequestDelegate
服務(wù)器接受到抵達的HTTP請求之后會構(gòu)建一個描述當(dāng)前請求的原始上下文,服務(wù)器的類型決定了這個原始上下文的類型,比如在我們模擬管道默認采用的HttpListenerServer由于采用HttpListener來監(jiān)聽、接收并響應(yīng)請求,所以它對應(yīng)的原始上下文是一個HttpListenerContext對象。但是對于管道的后續(xù)部分,即由注冊的中間件構(gòu)建的鏈表,它們需要采用統(tǒng)一的方式來處理請求,所以服務(wù)器最終會根據(jù)原始的上下文來創(chuàng)建一個抽象的HTTP上下文,后者通過抽象類HttpContext來表示。
我們不僅可以利用這個HttpContext獲取描述當(dāng)前請求的上下文信息,同樣可以利用它來實現(xiàn)對響應(yīng)的控制。針對當(dāng)前請求的任何處理操作總是在這么一個上下文中進行,所以一項請求處理任務(wù)完全可以抽象成一個類型Func<HttpContext,Task>的委托來表示,實際上具有如下定義的RequestDelegate委托具有類似的定義。
1: public delegate Task RequestDelegate(HttpContext context);
每個中間件都承載著獨立的請求處理任務(wù),它本質(zhì)上也體現(xiàn)了在當(dāng)前HttpContext下針對請求的處理操作,那么為什么中間件不直接通過一個RequestDelegate對象來表示,而是表示為一個類型為Func<RequestDelegate, RequestDelegate>的委托對象呢?原因很簡單,中間件并不孤立地存在,所有注冊的中間件最終會根據(jù)注冊的先后順序組成一個鏈表,每個中間件不僅僅需要完成各自的請求處理任務(wù)外,還需要驅(qū)動鏈表中的下一個中間件。