ASP.NET Core管道雖然在結構組成上顯得非常簡單,但是在具體實現(xiàn)上卻涉及到太多的對象,所以我們在 “通過重建Hosting系統(tǒng)理解HTTP請求在ASP.NET Core管道中的處理流程”(上篇、中篇、下篇) 中圍繞著一個經過極度簡化的模擬管道講述了真實管道構建的方式以及處理HTTP請求的流程。在本系列 中,我們會還原構建模擬管道時可以舍棄和改寫的部分,向讀者朋友們呈現(xiàn)一個真是的HTTP請求處理管道。 ASP.NET Core 的請求處理管道由一個服務器與一組有序排列的中間件構成,前者僅僅完成請求監(jiān)聽、接收和響應這些與底層網(wǎng)絡相關的工作,至于請求接收之后和響應之前的所有工作都交給中間件來完成。ASP.NET Core的中間件通過一個類型Func<RequestDelegate, RequestDelegate>的委托對象來表示,而RequestDelegate也是一個委托,它代表一項請求處理任務。 [本文已經同步到《ASP.NET Core框架揭秘》之中]

目錄
一、RequestDelegate
二、HttpContext
    FeatureCollection
    DefaultHttpContext
    HttpContextFactory
三、ApplicationBuilder
    ApplicationBuilderFactory
    中間件類型
    中間件類型的注冊

一、RequestDelegate

服務器接受到抵達的HTTP請求之后會構建一個描述當前請求的原始上下文,服務器的類型決定了這個原始上下文的類型,比如在我們模擬管道默認采用的HttpListenerServer由于采用HttpListener來監(jiān)聽、接收并響應請求,所以它對應的原始上下文是一個HttpListenerContext對象。但是對于管道的后續(xù)部分,即由注冊的中間件構建的鏈表,它們需要采用統(tǒng)一的方式來處理請求,所以服務器最終會根據(jù)原始的上下文來創(chuàng)建一個抽象的HTTP上下文,后者通過抽象類HttpContext來表示。

我們不僅可以利用這個HttpContext獲取描述當前請求的上下文信息,同樣可以利用它來實現(xiàn)對響應的控制。針對當前請求的任何處理操作總是在這么一個上下文中進行,所以一項請求處理任務完全可以抽象成一個類型Func<HttpContext,Task>的委托來表示,實際上具有如下定義的RequestDelegate委托具有類似的定義。

 1: public delegate Task RequestDelegate(HttpContext context); 

每個中間件都承載著獨立的請求處理任務,它本質上也體現(xiàn)了在當前HttpContext下針對請求的處理操作,那么為什么中間件不直接通過一個RequestDelegate對象來表示,而是表示為一個類型為Func<RequestDelegate, RequestDelegate>的委托對象呢?原因很簡單,中間件并不孤立地存在,所有注冊的中間件最終會根據(jù)注冊的先后順序組成一個鏈表,每個中間件不僅僅需要完成各自的請求處理任務外,還需要驅動鏈表中的下一個中間件。