[MVC]專案客製化方式#2
前篇 [MVC]專案客製化方式 是透過 ActionFilterAttribute 來判斷在 Customized Area 中是否有對應的Controller及Action, 如果有就導過去。
今天看到「ASP.NET MVC Controller Dependency Injection for Beginners」,然後想到如果只考慮Controller的話,那就可以透過 自定的 ControllerFactory 來處理這件事。
以下筆著建立一個 自定的ControllerFactory ,判斷有客製化的Controller就產生客製化的Controller,並設定Area為Customized,如下,
public class CustomControllerFactory : IControllerFactory
{
public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
{
string customizeNamespace = "Customized";
string customizeTypeName = string.Format("{0}.Controllers.{1}Controller", customizeNamespace, controllerName);
string defaultTypeName = string.Format("{0}.Controllers.{1}Controller", string.Empty , controllerName);
Type[] types = System.Reflection.Assembly.GetExecutingAssembly().GetTypes();
Type controllerType = types.Where(t => t.FullName.EndsWith(customizeTypeName, StringComparison.InvariantCultureIgnoreCase)).SingleOrDefault();
if (controllerType == null)
{
controllerType =
types.Where(t => t.FullName.EndsWith(defaultTypeName, StringComparison.InvariantCultureIgnoreCase))
.SingleOrDefault();
}
else
{
requestContext.RouteData.DataTokens["area"] = customizeNamespace;
}
IController controller = Activator.CreateInstance(controllerType) as Controller;
return controller;
}
public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(System.Web.Routing.RequestContext requestContext, string controllerName)
{
return SessionStateBehavior.Default;
}
public void ReleaseController(IController controller)
{
IDisposable disposable = controller as IDisposable;
if (disposable != null)
disposable.Dispose();
}
}
然後在 Global.asax.cs 中設定使用 自定的ControllerFactory ,如下,
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
//加入設定使用 自定的ControllerFactory
RegisterCustomControllerFactory();
}
private void RegisterCustomControllerFactory()
{
IControllerFactory factory = new CustomControllerFactory();
ControllerBuilder.Current.SetControllerFactory(factory);
}
所以透過 自定的ControllerFactory ,只要有客製的Controller就轉過去,如果沒有的話,就轉回到原本的Controller。
希望對大家在開發產品客製化上,有所幫助,如有其他的想法,也請讓我知道,謝謝!
另外,如果將「_ViewStart.cshtml」檔案Copy到Area之中,執行時,會發生以下的錯誤,
Type ‘ASP._Page__ViewStart_cshtml’ does not inherit from ‘System.Web.WebPages.StartPage’.
可參考「Sharing a single _ViewStart across areas in ASP.NET MVC」,
將Views目錄中的 system.web.webPages.razor 區段 Copy 到 Root的Web.config之中。
參考資料
ASP.NET MVC Controller Dependency Injection for Beginners
Sharing a single _ViewStart across areas in ASP.NET MVC
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^