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为控制器的类库

代码如下(示例):

// 源文件头信息:
// <copyright file="ControllersFactory.cs">
// Copyright(c)2014-2034 Kencery.All rights reserved.
// 个人博客:http://www.cnblogs.com/hanyinglong
// 创建人:韩迎龙(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"}
    );

第三种方法

 第三种方法是我这段时间建立MVC项目使用的方法,不像上面那么复杂,只要namespace命名等规范,其实在MVC项目下的Controller就是DLL文件,所以当我们将控制器分离成类库移除去的时候,直接在MVC项目中添加DLL文件即可实现分离


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值