Agenda
前言
前面和大家分享StepManager
是如何建立管道和依序呼叫IHttpModule
註冊事件
查看原始碼好站 Reference Source
此文的程式碼比較多我會在原始碼上邊上說明相對應編號方便大家觀看
今天跟大家分享HttpAppliaction
是如何找到要執行的IHttpHandler
物件.
呼叫HttpAppliaction取得HttpHandler並呼叫
在ApplicationStepManager
的IExecutionStep
中重要的實現類別有兩個
MapHandlerExecutionStep
:找到執行IHttpHander
CallHandlerExecutionStep
MapHandlerExecutionStep程式碼解說
前面說過IExecutionStep
最核心就是要找到一個Execute
方法
MapHandlerExecutionStep
的Execute
方法是為了找到一個要執行的HttpHander
每次請求都會呼叫
HttpContext.Handler
屬性.
MapHttpHandler
會依照下面權重來取得HttpHander
物件.
context.RemapHandlerInstance
如果有物件就優先返回(很重要因為這就是Asp.net MVC使用的HttpHander
物件)- 透過
IHttpHandlerFactory
工廠來取得物件,依照我們在Config
註冊的HttpHander
對應資料- 副檔名
*.ashx
泛型處理常式透過SimpleHandlerFactory
- 副檔名
*.aspx
泛型處理常式透過PageHandlerFactory
- 副檔名
想知道更多可以查看
applicationhost.config
註冊表
1 | internal class MapHandlerExecutionStep : IExecutionStep { |
MapHandlerExecutionStep
是為了找到我們要執行的HttpHandler
物件.
1 | if (handler != null){ |
在一開始先判斷handler
是否已經有值如果有就直接返回(這個很重要因為這是為什麼MVC
,WebAPI
可以運作且不用在Config
設定配對IHttpHandlerFactory
原因).
只需要在
MapHandlerExecutionStep
執行前將context.RemapHandlerInstance
給一個HttpHandler
物件即可.
CallHandlerExecutionStep程式碼解說
CallHandlerExecutionStep
物件透過context.Handler
可以找到要執行的HttpHandler
,這邊也是優先判斷是否可執行異步請求.
- 異步呼叫
beginProcessRequestDelegate
方法(此方法將實現IHttpAsyncHandler
物件封裝成一個Func<T, AsyncCallback, object, IAsyncResult>
委派方法),之後再調用返回一個IAsyncResult
物件(處理後結果最後呼叫EndProcessRequest
方法). - 同步呼叫
ProcessRequest
:判斷context.Handler
不是IHttpAsyncHandler
型別就值型同步動作
1 | // execution step -- call HTTP handler (used to be a separate module) |
小結:
希望可以讓大家對於為什麼Asp.net
為何可以針對IHttpModule
擴充且為何最後都會請求一個IHttpHandler
有更深入的了解.
微軟透過一系列的管道設計模式提供有高度擴展的系統對外提供一個IHttpHandler
讓我們可以客製化擴充要執行的請求.
對於此次請求又有IHttpModule
可對於HttpApplication
事件做擴充(透過AOP編成方式).
今天之後我們會開始講解Asp.net MVC相關的原始程式碼.
此文作者:Daniel Shih(石頭)
此文地址: https://isdaniel.github.io/ithelp-day7/
版權聲明:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!