[MVC]專案客製化方式#2

[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);
} 

 

image

image

 

所以透過 自定的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之中。

 

參考資料

[MVC]專案客製化方式

ASP.NET MVC Controller Dependency Injection for Beginners

Sharing a single _ViewStart across areas in ASP.NET MVC

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^