以前講了管道流中的Module與Hndler。如今咱們能夠去自定義Module和Handler web
其實很簡單,一共須要三個步驟 緩存
和自定義Module相似 app
注:MVC也是這麼去作的,註冊了Mvc的Module和Mvc的Handler。 函數
MVC的路由也是經過Module去攔截,而後找到匹配的路由。而後拿到handler激活Controller。下面解析一下過程 this
在MVC中咱們在RouteConfig中配置路由。結構是這樣的 url
那麼截獲它的是UrlRoutingModule => spa
=> 這個moudule如咱們自定義的同樣,繼承了IHttpModule。註冊了事件 application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);。須要說明的 是,這裏也有了緩存。只有第一次纔會去執行 3d
=> RouteData routeData = this.RouteCollection.GetRouteData(context); 映入眼簾的是這段代碼。GetRouterData就是去獲取匹配的路由 blog
=> 而後看到了一個foreach,是的。foreach。按照個人觀察,它是一個鍵值對。這裏就知道了,爲何經常使用的路由要放到前面。能夠快速遍歷到。這裏的值是RouteBase,它是一個抽象類。具體的實現應該在子類裏面。 繼承
=> 繼續會看到,獲取了RouteHandler!。那麼RouteHandler是什麼呢。
=> 轉到了MapRoute也就是咱們的定義路由方法,看到了一個MvcRouteHandler。再轉到Route的構造函數
=> 能夠看到他是一個IRouteHandler的實現!以前Module的圖繼續往下走,看到了調用了GetHttpHandler這個方法。能夠看到其實它就至關於一個工廠。那麼拿到的又是什麼呢
=> 能夠發現,返回了一個MvcHandler。它就是咱們的最終主角。這時候一系列操做就完成了,MvcHandler的ProcessRequest方法,下圖是同步方法,這裏拿到了IController。而後再Execute。 IController是ControllerBase類繼承的接口,Execute中又調用了ExecuteCore方法。也就是Controller類的實現。到此管道結束
這張圖就是MVC的管道總體流程
咱們在定義了MapRoute後,到底放到了什麼地方呢?又是怎麼對值進行過濾的呢?道兄莫慌,下面一一分析。
注意,這裏並無實踐。由於斷點一直下不去。因此引用了別人的圖。待以後再實踐吧
上圖不難發現,除了MapRoute外還有IngoreRoute。 進入到Blobal中能夠看到註冊路由用的是RouteTable.Routes
RouteTable
=> Routes [RouteCollection]
先是建立一個Route而後添加到了咱們的 routes [RouteCollection]中
Route route = new Route(url, new MvcRouteHandler()) {
Defaults = CreateRouteValueDictionaryUncached(defaults),
Constraints = CreateRouteValueDictionaryUncached(constraints),
DataTokens = new RouteValueDictionary()
};
ConstraintValidation.Validate(route);
if ((namespaces != null) && (namespaces.Length > 0))
{
route.DataTokens["Namespaces"] = namespaces;
}
routes.Add(name, route);
是的沒錯。這裏建立一個IgnoreRouteInternal,而後也添加到了Routes中。
IgnoreRouteInternal route = new IgnoreRouteInternal(url) {
Constraints = CreateRouteValueDictionaryUncached(constraints)
};
ConstraintValidation.Validate(route);
routes.Add(route);
還記得,咱們的Route的構造函數須要一個IRouteHandler。這個IgnoreRouteInternal則是Route的子類,那麼它傳入的是什麼呢?
能夠看到,是StopRoutingHandler,這就不難猜到了。回到UrlRoutingModule代碼中,從下圖能夠發現,這裏拿到了RouteHandler以後,進行了判斷。若是是StopRoutingHandler則直接把請示打回去。
MapRoute有幾個重載,有這樣一個參數,contraints。它能夠對咱們的參數進行一些約束。
一個簡單的玩法,這裏對id這個參數進行了約束,使其必須是數字。不只是id,其它的片斷也能夠進行約束。
看一下源碼,其實這個方法就是進行匹配。在ProcessConstraion中,拿到了IRouteConstrraint。若是咱們的表達式是strng,就進行正則匹配。
上面有一個Match。這個是最吊的自定義。