看蔣老師MVC的書第二個大收獲可以是算是看了這個迷你ASP.NET MVC框架了,雖然它遠不如真正ASP.NET MVC(下文簡稱“MVC”)那么復雜龐大,但在迷你版中繞來繞去也夠嗆的。這部分我看了幾回,也沒完完全全地弄清里面的結構,但要透徹了解整個MVC框架,貫通了整個迷你MVC框架必不可少,沒了迷你的作為基礎,在看完整框架時也不知道走到哪一步了。貫通整個框架雖然復雜,但我覺得可以從分層次的角度去看整個框架,化整為零,那么難度就降下來了。
首先對於平常的Http請求來了,服務器對作相應的處理,處理完畢之后就會給瀏覽器一個Http響應。最簡單的就是瀏覽器發出來一個對index.htm頁面的請求,服務器就會讀取index.htm文件的內容然后把內容包含在報文里面傳遞給瀏覽器昨晚響應。這個就是單純的URL與物理文件綁定,在ASP.NET里面多加了路由機制,它就使得URL與物理文件分離。MVC里面其中一個重要部分就是路由機制,整個請求響應過程就變成了
也就是接收到一個請求之后用IhttpModule接口把請求攔截下來,按照路由規則分析了URL並匹配好對應的路由之后,用一個實現IHttpHandler接口的類的實例去做相應的處理,處理完畢就返回HttpResponse到瀏覽器。這個就是MVC框架的最頂層部分了。在這里我們還沒看到平時在使用MVC是接觸到的Route,Controller和Action。如果跟兩個接口扯上關系的話,那就是Route主要是在HttpModule部分被使用,Controller和Action是在HttpHandler部分被使用。大框架已經定好的話,現在可以細化了,可以分別從HttpModule和HttpHandler去看整個流程。
IHttpModule
由UrlRouteModule去實現這個接口,處理過程大致是根據當前的請求上下文,構造HttpContextWapper對象。通過全局路由表來匹配當前請求的URL,獲取到路由之后就通過路由和HttpContextWapper構造出請求上下文(RequestContext),從路由中獲取一個實現IRouteHandler接口的類的實例,那是個MvcRouteHandler的實例,從那個實例中調用GetHttpHandler方法獲取到一個實現IHttpHandler接口的類的實例,最后從通過HttpContextWapper把IHttpHandler更替過去,IHttpModule的部分就完結了,接下來到HttpHandler部分的處理了。整個處理的流程也如下圖所示
IHttpHandler
由MvcHandler來實現這個接口,在HttpModule部分已經把路由對象處理好了,MVC中剩下的調用控制器中的行為方法,傳入參數,綁定相關模型,處理完畢之后返回一個ActionResult,最終通過視圖的內容作為響應報文呈現在瀏覽器上。MvcHandler的處理就在ProcessRequset方法里執行。詳細的流程如下,首先從傳入的HttpRequestContext中獲取控制器的名字,Controller控制器是通過控制器工廠獲取的,控制器工廠是從ControllerBuilder中得到。Controller執行Execute方法,傳入RequestContext參數。就會執行相應的行為方法。流程如下圖
但是其實還有更多操作包含在Execute方法里面,因為還需要執行行為方法,從Route中獲取參數傳到行為方法里面,返回ActionResult等。
在ControllBase調用Execute方法里,通過傳入的請求上下文(RequestContext)和控制器自身構造出一個控制器上下文(ControllerContext),最后調用一個實現IActionInvoker的接口執行行為方法,如下圖所示
這里又有一個InvokeAction方法,里面核心部分就是通過反射調用Controller的行為方法,至於行為方法需要傳入的參數,生成ParameterInfo實例是通過了調用IModelBinder接口的方法,通過上下文獲取路由的參數,也是利用了反射機制設值。方法調用完畢后返回的是一個ActionResult抽象類的實例,那么最后執行了ActionResult的ExecuteResult方法,把響應的頁面的內容生成出來。如下圖所示
HttpHandler的操作就分成了這幾塊,如果湊在一起的話,圖成這樣了
對於HttpModule部分,有幾個類的關系還是要理順一下。
整幅圖其實沒有按照UML的格式去畫的,那個我也已經忘了,我畫圖的目的在於羅列各個類,而且把類與類之間的調用標示出來,對於一個方法,從類圖左側引線出去的,那是返回,從右側引線出去的那是傳入。
整個框架用的接口還是挺多的,這個覺得就能給我一種達到解耦的目的。方法的調用不通過類來直接調用,而是通過接口的調用,這樣就排除了主調類對被調類的訪問,不需要知道其細節。
以上便是我對迷你MVC的學習筆記,可能有些園友覺得我多此一舉,不管怎樣多了解一點還是有好處的,以上有理解錯的歡迎大家指出,謝謝!
熟悉其情況 查看其結構 理解其本質 思考其改進