ASP.NET MVC隨想錄(3):建立自定義的Middleware中介軟體

發表於2015-09-09

經過前2篇文章的介紹,相信大家已經對OWIN和Katana有了基本的瞭解,那麼這篇文章我將繼續OWIN和Katana之旅——建立自定義的Middleware中介軟體。

何為Middleware中介軟體

Middleware中介軟體從功能上可以理解為用來處理Http請求,當Server將Http請求封裝成符合OWIN規範的字典後,交由Middleware去處理,一般情況下,Pipeline中的Middleware以鏈式的形式處理Http請求,即每一個Middleware都是最小的模組化,彼此獨立、高效。

從語法上理解Middleware的話,他是一個應用程式委託(Func<IDictionary<string, object>, Task>)的例項,通過使用IAppBuilder 介面的Use或者Run方法將一個Middleware插入到Pipeline中,不同的是使用Run方法不需要引用下一個Middleware,即他是Pipeline中最後的處理元素。

使用Inline方式註冊Middleware

使用Use方法可以將一個Middleware插入到Pipeline中,值得注意的是需要傳入下一個Middleware的引用,程式碼如下所示:

上述程式碼中,例項化了一個委託,它需要傳入下一個Pipeline中的Middleware引用同時返回一個新的Middleware並插入到Pipeline中。因為是非同步的,所以別忘了async、await關鍵字。

使用Inline+ AppFunc方式註冊Middleware

為了簡化書寫,我為應用程式委託(Func<IDictionary<string, object>, Task>)型別建立了別名AppFunc:

所以又可以使用如下方式來講Middleware新增到Pipeline中:

考慮到業務邏輯的增長,有必要將Lambda表示式中的處理邏輯給分離開來,所以對上述程式碼稍作修改,提取到一個名為Invoke的方法內:

雖然將業務邏輯抽取到一個方法中,但Inline這種模式對於複雜的Middleware還是顯得不夠簡潔、易懂。我們更傾向於建立一個單獨的類來表示。

定義原生Middleware類的形式來註冊Middleware

如果你只想簡單的跟蹤一下請求,使用Inline也是可行的,但對於複雜的Middleware,我傾向於建立一個單獨的類,如下所示:

最後,依舊是通過Use方法來將Middleware新增到Pipeline中:

上述程式碼中,IAppBuilder例項的Use方法新增Middleware至Pipeline與Inline方式有很大不同,它接受一個Type而非Lambda表示式。在這種情形下,建立了一個Middleware型別的例項,並將Pipeline中下一個Middleware傳遞到建構函式中,最後當Middleware被執行時呼叫Invoke方法。

注意Middleware是基於約定的形式定義的,需要滿足如下條件:

  • 建構函式的第一個引數必須是Pipeline中下一個Middleware
  • 必須包含一個Invoke方法,它接收Owin環境字典,並返回Task

使用Katana Helper來註冊Middleware

程式集Microsoft.Owin包含了Katana為我們提供的Helper,通過他,可以簡化我們的開發,比如IOwinContext封裝了Owin的環境字典,強型別物件可以通過屬性的形式獲取相關資料,同時為IAppBuilder提供了豐富的擴充套件方法來簡化Middleware的註冊,如下所示:

當然我們也可以定義一個Middleware類並繼承OwinMiddleware,如下所示:

然後將其新增到Pipeline中:

Middleware的執行順序

在完成上面Middleware註冊之後,在Configuration方法的最後新增最後一個的Middleware中介軟體,注意它並不需要對下一個Middleware的引用了,我們可以使用Run方法來完成註冊:

值得注意的是,Pipeline中Middleware處理Http Request順序同註冊順序保持一致,即和Configuration方法中書寫的順序保持一致,Response順序則正好相反,如下圖所示:

最後,執行程式,檢視具體的輸出結果是否和我們分析的保持一致:

小結

在這篇文章中,我為大家講解了自定義Middleware的建立,Katana為我們提供了非常多的方式來建立和註冊Middleware,在下一篇文章中,我將繼續OWIN和Katana之旅,探索Katana和其他Web Framework的整合。

相關文章