ASP.NET MVC中將控制器分離到類庫的實現


前言

  在ASP.NET MVC的開發中,我們創建完項目之后,ASP.NET MVC是已Model-Controller-View的形式存在的,在創建項目自動生成的內容上Model我們很容易分離成類庫,所以這里不予說明,那么這時候我們就像Controller是不是也能夠分離出去呢?答案是肯定的,下面我們探討一下Controller如何分離出去。

  這里我提供兩種分離的方法,一是重寫方法繼承自IControllerFactory接口,實現里面的方法,二是MVC提供了直接在路由注冊里面去控制控制器的書寫,下面就這兩種類型簡單貼一下代碼。

第一種方法

  代碼如下:當寫完代碼之后再路由中注冊。提示:實現完成之后必須在路由規則方法(RegisterRoutes)里面進行注冊,注冊代碼如下:

    ControllerBuilder.Current.SetControllerFactory(new ControllersFactory("BookSystem_Controllers")); //BookSystem_Controllers為控制器的類庫

 

  1 // 源文件頭信息:
  2 // <copyright file="ControllersFactory.cs">
  3 // Copyright(c)2014-2034 Kencery.All rights reserved.
  4 // 個人博客:http://www.cnblogs.com/hanyinglong
  5 // 創建人:韓迎龍(kencery)
  6 // 創建時間:2015-6-18
  7 // </copyright>
  8 
  9 using System;
 10 using System.Reflection;
 11 using System.Web.Mvc;
 12 using System.Web.Routing;
 13 using System.Web.SessionState;
 14 
 15 namespace BookSystem_Controllers
 16 {
 17     /// <summary>
 18     /// 重寫注冊控制器的方法,使之能夠將控制器管分離到其它類庫中實現
 19     /// <auther>
 20     ///     <name>kencery</name>
 21     ///     <date>2015-6-18</date>
 22     /// </auther>
 23     /// </summary>
 24     /// 說明:IControllerFactory接口含有三個需要實現的方法:CreateController,GetControllerSessionBehavior,ReleaseController
 25     /// 使用:在MVC App_Start文件夾中的RouteConfig中的方法RegisterRoutes中的第一行中寫入下面注冊語句,Global.asax中也可注冊,放到注冊路由之前即可
 26     /// ControllerBuilder.Current.SetControllerFactory(new ControllersFactory("BookSystem_Controllers"));  //BookSystem_Controllers為控制器的類庫
 27     public class ControllersFactory : IControllerFactory
 28     {
 29         private readonly string _assemblyName;
 30         private readonly string _controlerDefaultNameSpage;
 31         private Assembly _controllerAssembly;
 32 
 33         /// <summary>
 34         /// 獲取控制器所在的程序集名稱
 35         /// </summary>
 36         public string AssemblyName
 37         {
 38             get { return _assemblyName; }
 39         }
 40 
 41         /// <summary>
 42         /// 獲取控制器的默認命名空間
 43         /// </summary>
 44         public string ControlerDefaultNameSpage
 45         {
 46             get { return _controlerDefaultNameSpage; }
 47         }
 48 
 49         /// <summary>
 50         /// 獲取控制器所在的程序集的Assembly實例
 51         /// </summary>
 52         public Assembly ControllerAssembly
 53         {
 54             get
 55             {
 56                 return _controllerAssembly ?? (_controllerAssembly = Assembly.Load(AssemblyName)); //加載控制器信息
 57             }
 58         }
 59 
 60         /// <summary>
 61         /// 構造函數實例化
 62         /// </summary>
 63         /// <param name="assemblyName"></param>
 64         public ControllersFactory(string assemblyName)
 65         {
 66             _assemblyName = assemblyName;
 67         }
 68 
 69         /// <summary>
 70         /// 構造函數實例化
 71         /// </summary>
 72         /// <param name="assemblyName"></param>
 73         /// <param name="controlerDefaultNameSpage"></param>
 74         public ControllersFactory(string assemblyName, string controlerDefaultNameSpage)
 75         {
 76             _assemblyName = assemblyName;
 77             _controlerDefaultNameSpage = controlerDefaultNameSpage;
 78         }
 79 
 80         /// <summary>
 81         /// 獲取控制器類的全名
 82         /// </summary>
 83         /// <param name="controllerName">控制器名稱</param>
 84         public string GetControllerFullName(string controllerName)
 85         {
 86             return string.Format("{0}.{1}Controller",
 87                 string.IsNullOrEmpty(ControlerDefaultNameSpage) ? AssemblyName : ControlerDefaultNameSpage,
 88                 controllerName);
 89         }
 90 
 91         /// <summary>
 92         /// 獲取控制器實例對象,根據controllerName生成一個沒有請求上下文對象的空的控制器,在為此控制器制定ControllerContext對象,然后返回控制器實例
 93         /// </summary>
 94         /// <param name="requestContext"></param>
 95         /// <param name="controllerName"></param>
 96         public IController CreateController(RequestContext requestContext, string controllerName)
 97         {
 98             var controller = ControllerAssembly.CreateInstance(GetControllerFullName(controllerName)) as Controller;
 99             if (controller == null)
100                 return null;
101             if (controller.ControllerContext == null)
102             {
103                 controller.ControllerContext = new ControllerContext(requestContext, controller);
104             }
105             else
106             {
107                 controller.ControllerContext.RequestContext = requestContext;
108             }
109             return controller;
110         }
111 
112         /// <summary>
113         /// 返回請求的會話狀態的支持類型
114         /// </summary>
115         /// <param name="requestContext"></param>
116         /// <param name="controllerName"></param>
117         public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
118         {
119             var controllerType = ControllerAssembly.GetType(GetControllerFullName(controllerName), true, true);
120             var sessionStateAttr =
121                 Attribute.GetCustomAttribute(controllerType, typeof (SessionStateAttribute), false) as
122                     SessionStateAttribute;
123             return sessionStateAttr == null ? SessionStateBehavior.Default : sessionStateAttr.Behavior;
124         }
125 
126         /// <summary>
127         /// 釋放資源
128         /// </summary>
129         /// <param name="controller"></param>
130         public void ReleaseController(IController controller)
131         {
132             var idDisposable = controller as IDisposable;
133             if (idDisposable != null)
134             {
135                 idDisposable.Dispose();
136             }
137         }
138     }
139 }

第二種方法

  路由注冊方法代碼如下:缺點是,如果有多個注冊路由的規則,都必須記得添加namespaces屬性,否則會出現錯誤

1      //系統默認路由
2             routes.MapRoute(
3                 name: "Default",
4                 url: "{controller}/{action}/{id}",
5                 defaults: new {controller = "Login", action = "Index", id = UrlParameter.Optional},
6                 namespaces: new string[] {"BookSystem_Controllers"}
7     );

 

第三種方法

  第三種方法是我這段時間建立MVC項目使用的方法,不像上面那么復雜,只要namespace命名等規范,其實在MVC項目下的Controller就是DLL文件,所以當我們將控制器分離成類庫移除去的時候,直接在MVC項目中添加DLL文件即可實現分離


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM