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

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

一、RequestDelegate

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

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

 1: public delegate Task RequestDelegate(HttpContext context); 

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