你的位置:首页 > ASP.net教程

[ASP.net教程]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       else106       {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) as122           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   );