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