大家知道ASP.NET MVC正式發布以來,受到開發人員的瘋狂追捧,園子裡MVC系列文章更是層出不窮,套用ASP.NET開發人員需要學習ASP.NET MVC麼(英文地址)一文所說的:
WebForms是個謊言,它是一個被種種謊言和欺騙所包圍著的抽象機制。你對WebForms所做的一切都與Web無關-它幫你做了本該你自己做的事。
朋友們,這可是件大事(至少對我來說):你工作在謊言中。Web是“無”狀態的,它依賴一種叫做HTML的東西,並使用另一種叫做HTTP的東西通過電纜將HTML發來發去-你需要瞭解它、熱愛它並在骨子裡感受它。
ASP.NET MVC不是一個“束縛你手腳”的架構,也不是一個“ASP.NET入門”架構,你可以完全控制所有的東西。在Web的世界裡,UI還沒有標準化到可以使用架構來控制,並以一種“標準”的方式來產生。
這些都充分說明了使用MVC架構進行Web開發的必要性,至於更多的MVC和WebForms的特性,可以看看我無意中找到的一篇文章Asp.NET MVC and Asp.NET WebForms Features,至於更多關於這兩者選擇性問題我持保留意見,只能說合適的才是最好的,有一點我想事先說明一下,選擇MVC能進行更多的控制但同時也意味著需要編寫更多的代碼(我是比較樂意的)。
最近在一個項目裡使用了MVC開發,所以就閱讀了一下MVC源碼,真的非常棒,可擴充性非常強,可以說處處都可以擴充,Simone Chiaretta有篇文章被翻譯了:【翻譯】ASP.NET MVC中你必須知道的13個擴充點。
本文我將介紹擴充IControllerFactory的一個應用,通過擴充DefaultControllerFactory來實現Controller. ActionInvoker的替換,然後擴充IActionInvoker實現返回不同的ViewResult, 本文只實現一些簡單的功能,僅當拋磚引玉。閱讀之前你需要熟悉asp.net mvc具體流程,asp.net mvc流程初探雖然只是“初探”,但讓你粗略瞭解asp.net mvc流程已經足夠。
首先我們擴充IControllerFactory,讓它替換ActionInvoker為我們自己擴充的TestControllerActionInvoker:
public class TestControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
IController iController = base.GetControllerInstance(controllerType);//如果用到了依賴注入,可從注入容器擷取
if (typeof(Controller).IsAssignableFrom(controllerType))
{
Controller controller = iController as Controller;
if (controller != null)
controller.ActionInvoker = new TestControllerActionInvoker();//同樣可以從注入容器擷取
return iController;
}
return iController;
}
}
然後擴充IActionInvoker:
public class TestControllerActionInvoker : ControllerActionInvoker
{
protected override ActionResult CreateActionResult(ControllerContext controllerContext, ActionDescriptor actionDescriptor, object actionReturnValue)
{
if (actionReturnValue == null)
{
return new XXXResult();//可以處理自己的ViewResult邏輯
}
if (typeof(ActionResult).IsAssignableFrom(actionReturnValue.GetType()))
return actionReturnValue as ActionResult;
controllerContext.Controller.ViewData.Model = actionReturnValue;
//可以根據返回的類型返回進行相應的ViewResult
return new TTTResult { ViewData = controllerContext.Controller.ViewData, TempData = controllerContext.Controller.TempData };
}
}
這裡只是簡單的對IActionInvoker的管線中的Action方法執行後的傳回值進行處理,當然IActionInvoker能擴充的地方非常多,這樣的好處是你在具體的Action裡不必把過多的精力放在View這一層面,可維護性和可擴充性也就上了一個層次了。
最後,別忘記對ControllerBuilder進行設定ControllerFactory操作:
ControllerBuilder.Current.SetControllerFactory(new TestControllerFactory());
好了本文就簡單介紹到這,希望你能在自己的項目中根據自己的需要進行擴充,如果你項目中用到了依賴注入,需要對IControllerFactory進行擴充你可以參照MvcContrib和Ninject Controller Factory,至於ASP.NET MVC的IActionInvoker-ControllerActionInvoker主要任務是是尋找Action、調用Action方法以及相關的Filter、執行得到ActionResult,可以說存在了大量的asp.net mvc執行邏輯,如果你需要改變這些約定,那就放開了去擴充吧,這裡有個樣本:NinjectActionInvoker I developed to allow injection of dependencies inside filters。