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

[ASP.net教程]MVC项目插件化改造


  现在正在做的项目是以长沙某个客户的需求为原型进行开发的,随着业务的拓展,其他城市相同行业的客户也有类似的需求,在进行投标时,每个客户都有自己的页面和功能要求,如果单纯用长沙客户的软件版本,无法完全满足标书要求,因此需要对项目进行改造,考虑采用MVC插件化方式。

  现有项目使用的技术点主要是MVC+EF+jQuery,改造思路考虑将每一个功能模块抽取为一个插件,在主Web项目中引用各插件,并将插件的css、js、views等文件拷贝到主Web项目的Plugins文件夹下。当有新客户提出个性化需求时,将涉及到的模块插件复制一份,然后进行个性化改造,新插件和原插件在mvc 路由上一模一样,插件的名称也一样,这样对于主Web项目来说两个插件就如同一个一样。项目其他层(Biz、Model等其他类库)保持不变。

  具体改造方法:

  插件是一个MVC项目,要求必须包含:Controllers(控制器)、Models(ViewModel)、Content(样式表)、Scripts、Views文件夹。

  

  项目属性中的生成事件中,添加后期生成事件命令行:

rd /s /q $(SolutionDir)MyApplication.Web\Plugins\Devicexcopy /s /y $(ProjectDir)Views $(SolutionDir)MyApplication.Web\Plugins\Device\Views\xcopy /s /y $(ProjectDir)Content $(SolutionDir)MyApplication.Web\Plugins\Device\Content\xcopy /s /y $(ProjectDir)Scripts $(SolutionDir)MyApplication.Web\Plugins\Device\Scripts\

  分别用于:清空删除主Web项目插件目录、拷贝视图文件夹到主Web项目、拷贝样式表文件夹到主Web项目、拷贝js文件夹到主Web项目。这样就能实现在插件编译通过后,自动将相应的插件文件复制到主Web项目的Plugins下,方便调试。

  

 

  每个插件中都添加一个自启动类(要求是静态的)PluginStartUp,类中包含:插件名称、初始化方法、Razor静态文件导入扩展(css、js)。

  1.自启动类属性

  .Net Framework 4.0后提供了PreApplicationStartMethodAttribute属性,提供对应用程序启动的扩展支持。

  https://msdn.microsoft.com/zh-cn/library/system.web.preapplicationstartmethodattribute.aspx 

   使用时,将PreApplicationStartMetod的声明写在自启动类的命名空间前。

[assembly: System.Web.PreApplicationStartMethod(typeof(MyApplication.Plugins.Device.PluginStartUp), "Init")]namespace MyApplication.Plugins.Device{    /// <summary>    /// 插件自启动类,用于注册插件    /// </summary>    public static class PluginStartUp    {    } }

  2.插件名称

  插件名称为自启动类的属性,作为本插件的唯一标识。

    public static string Name    {      get      {        return "Device";      }    }

   3.插件初始化方法

  初始化包括注册路由和Razor视图引擎。

  将插件中的Controller注册为一个Area,主Web项目引用插件后就会把每一个插件当作一个域。

  注册视图引擎,主要是添加View的寻找路径,即/Plugins/插件名称/Views 路径。

    /// <summary>    /// 插件初始化    /// </summary>    public static void Init()    {      RegRoute();      RegViewEngine();    }    /// <summary>    /// 注册视图引擎    /// </summary>    private static void RegViewEngine()    {      ViewEngines.Engines.Add(new RazorViewEngine { AreaViewLocationFormats = new[] { "~/Plugins/" + Name + "/Views/{1}/{0}" } });    }    /// <summary>    /// 注册插件路由    /// </summary>    public static void RegRoute()    {      RouteTable.Routes.MapRoute(        "Device",        "/Device/{controller}/{action}/{id}",        new { controller = "DeviceHome", action = "Index", id = UrlParameter.Optional }).DataTokens["area"] =        Name;    }

  4.Razor扩展方法

  在View页面中引入css和js文件时,如果用插件中的相对路径,在引入到主Web项目后则会找不到文件,因此需要提供一个导入css和js文件的Html扩展方法,在View页面中使用该方法引入文件,方法内将路径格式化。

    /// <summary>    /// 导入css, Razor Html扩展    /// </summary>    /// <param name="helper"></param>    /// <param name="cssName"></param>    /// <returns></returns>    public static IHtmlString ImportCss(this HtmlHelper helper, string cssName)    {      return helper.Raw(string.Format("<link href=\"/Plugins/{0}/Content/{1}\" type='text/css' rel='stylesheet' />", Name, cssName));    }    /// <summary>    /// 导入js, Razor Html扩展    /// </summary>    /// <param name="helper"></param>    /// <param name="jsName"></param>    /// <returns></returns>    public static IHtmlString ImportJs(this HtmlHelper helper, string jsName)    {      return helper.Raw(string.Format("<script src=\"/Plugins/{0}/Scripts/{1}\" ></script>", Name, jsName));    }

  在View页面内,使用这两个扩展方法引入文件。

@Html.ImportCss("device.css")@Html.ImportJs("device.js")

  以上就完成了原项目插件化的改造。主Web项目添加对插件的引用,当项目启动时,PluginStartUp类自动运行完成插件初始化。

  当有新项目个性化需求时,只需将插件复制一份,并修改插件内的controller、view、content、scripts等,Biz、Model都无需变化(前提是项目的主业务流程是一致的),主Web项目也无需变动,发布时,根据项目的情况,需要哪些插件就在Plugins下面保留哪些插件即可。