前言
在、ASP.NET MVC的開發中,我們創建完項目之後,ASP.NET MVC是已Model-Controller-View的形式存在的,在創建項目自動生成的內容上Model我們很容易分離成類庫,所以這裡不予說明,那麼這時候我們就像Controller是不是也能夠分離出去呢?答案是肯定的,下面我們探討一下Controller如何分離出去。
這裡我提供兩種分離的方法,一是重寫方法繼承自IControllerFactory接口,實現裡面的方法,二是MVC提供了直接在路由注冊裡面去控制控制器的書寫,下面就這兩種類型簡單貼一下代碼。
第一種方法
代碼如下:當寫完代碼之後再路由中注冊。提示:實現完成之後必須在路由規則方法(RegisterRoutes)裡面進行注冊,注冊代碼如下:
ControllerBuilder.Current.SetControllerFactory(new ControllersFactory("BookSystem_Controllers")); //BookSystem_Controllers為控制器的類庫
// 源文件頭信息: // <copyright file="ControllersFactory.cs"> // Copyright(c)2014-2034 Kencery.All rights reserved. // 創建人:韓迎龍(kencery) // 創建時間:2015-6-18 // </copyright> using System; using System.Reflection; using System.Web.Mvc; using System.Web.Routing; using System.Web.SessionState; namespace BookSystem_Controllers { /// <summary> /// 重寫注冊控制器的方法,使之能夠將控制器管分離到其它類庫中實現 /// <auther> /// <name>kencery</name> /// <date>2015-6-18</date> /// </auther> /// </summary> /// 說明:IControllerFactory接口含有三個需要實現的方法:CreateController,GetControllerSessionBehavior,ReleaseController /// 使用:在MVC App_Start文件夾中的RouteConfig中的方法RegisterRoutes中的第一行中寫入下面注冊語句,Global.asax中也可注冊,放到注冊路由之前即可 /// ControllerBuilder.Current.SetControllerFactory(new ControllersFactory("BookSystem_Controllers")); //BookSystem_Controllers為控制器的類庫 public class ControllersFactory : IControllerFactory { private readonly string _assemblyName; private readonly string _controlerDefaultNameSpage; private Assembly _controllerAssembly; /// <summary> /// 獲取控制器所在的程序集名稱 /// </summary> public string AssemblyName { get { return _assemblyName; } } /// <summary> /// 獲取控制器的默認命名空間 /// </summary> public string ControlerDefaultNameSpage { get { return _controlerDefaultNameSpage; } } /// <summary> /// 獲取控制器所在的程序集的Assembly實例 /// </summary> public Assembly ControllerAssembly { get { return _controllerAssembly ?? (_controllerAssembly = Assembly.Load(AssemblyName)); //加載控制器信息 } } /// <summary> /// 構造函數實例化 /// </summary> /// <param name="assemblyName"></param> public ControllersFactory(string assemblyName) { _assemblyName = assemblyName; } /// <summary> /// 構造函數實例化 /// </summary> /// <param name="assemblyName"></param> /// <param name="controlerDefaultNameSpage"></param> public ControllersFactory(string assemblyName, string controlerDefaultNameSpage) { _assemblyName = assemblyName; _controlerDefaultNameSpage = controlerDefaultNameSpage; } /// <summary> /// 獲取控制器類的全名 /// </summary> /// <param name="controllerName">控制器名稱</param> public string GetControllerFullName(string controllerName) { return string.Format("{0}.{1}Controller", string.IsNullOrEmpty(ControlerDefaultNameSpage) ? AssemblyName : ControlerDefaultNameSpage, controllerName); } /// <summary> /// 獲取控制器實例對象,根據controllerName生成一個沒有請求上下文對象的空的控制器,在為此控制器制定ControllerContext對象,然後返回控制器實例 /// </summary> /// <param name="requestContext"></param> /// <param name="controllerName"></param> public IController CreateController(RequestContext requestContext, string controllerName) { var controller = ControllerAssembly.CreateInstance(GetControllerFullName(controllerName)) as Controller; if (controller == null) return null; if (controller.ControllerContext == null) { controller.ControllerContext = new ControllerContext(requestContext, controller); } else { controller.ControllerContext.RequestContext = requestContext; } return controller; } /// <summary> /// 返回請求的會話狀態的支持類型 /// </summary> /// <param name="requestContext"></param> /// <param name="controllerName"></param> public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName) { var controllerType = ControllerAssembly.GetType(GetControllerFullName(controllerName), true, true); var sessionStateAttr = Attribute.GetCustomAttribute(controllerType, typeof (SessionStateAttribute), false) as SessionStateAttribute; return sessionStateAttr == null ? SessionStateBehavior.Default : sessionStateAttr.Behavior; } /// <summary> /// 釋放資源 /// </summary> /// <param name="controller"></param> public void ReleaseController(IController controller) { var idDisposable = controller as IDisposable; if (idDisposable != null) { idDisposable.Dispose(); } } } }
第二種方法
路由注冊方法代碼如下:缺點是,如果有多個注冊路由的規則,都必須記得添加namespaces屬性,否則會出現錯誤
//系統默認路由 routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new {controller = "Login", action = "Index", id = UrlParameter.Optional}, namespaces: new string[] {"BookSystem_Controllers"} );