当前位置:  首页  >  PHP资讯  >  业界资讯

对ASP.NET中的MVC引擎开发插系统进行详解

这篇文章主要为大家详细介绍了使用ASP.NETMVC引擎开发插件系统的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
这篇文章主要为大家详细介绍了使用ASP.NET MVC引擎开发插件系统的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

一、前言

我心中的插件系统应该是像Nop那样(更牛逼的如Orchard,OSGI.NET),每个插件模块不只是一堆实现了某个业务接口的dll,然后采用反射或IOC技术来调用,而是一个完整的mvc小应用,我可以在后台控制插件的安装和禁用,目录结构如下:

     

2.开发一个简易的插件管理类,这个类的作用就是在Application_Start之前就把Plugins各子目录中的dll拷贝到第1步指定的文件夹中,为了让demo尽可能简单,没有对重复的dll进行检测(比如插件中引用了ef程序集,主站点也引用了,在站点bin目录中已经存在ef的dll了,就没必要再把插件中的dll拷贝到上面设置的动态程序集目录中)


using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Web; using System.Web.Compilation; using System.Web.Hosting; [assembly: PreApplicationStartMethod(typeof(Plugins.Core.PreApplicationInit), "Initialize")] namespace Plugins.Core { public class PreApplicationInit { static PreApplicationInit() { PluginFolder = new DirectoryInfo(HostingEnvironment.MapPath("~/plugins")); ShadowCopyFolder = new DirectoryInfo(HostingEnvironment.MapPath("~/plugins/temp")); } ///  /// 插件所在目录信息 ///  private static readonly DirectoryInfo PluginFolder; ///  /// 程序应行时指定的dll目录 ///  private static readonly DirectoryInfo ShadowCopyFolder; public static void Initialize() { Directory.CreateDirectory(ShadowCopyFolder.FullName); //清空插件dll运行目录中的文件 foreach (var f in ShadowCopyFolder.GetFiles("*.dll", SearchOption.AllDirectories)) { f.Delete(); } foreach (var plug in PluginFolder.GetFiles("*.dll", SearchOption.AllDirectories).Where(i=>i.Directory.Parent.Name== "plugins")) { File.Copy(plug.FullName, Path.Combine(ShadowCopyFolder.FullName, plug.Name), true); } foreach (var a in ShadowCopyFolder .GetFiles("*.dll", SearchOption.AllDirectories) .Select(x => AssemblyName.GetAssemblyName(x.FullName)) .Select(x => Assembly.Load(x.FullName))) { BuildManager.AddReferencedAssembly(a); } } } }

3.如何让View引擎找到我们的视图呢?答案是重写RazorViewEngine的方法,我采用了约定大于配置的方式(假设我们的插件项目命名空间为Plugins.Apps.Sms,那么默认的控制器命名空间为Plugins.Apps.Sms.Controllers,插件生成后的文件夹必须为/Plugins/Plugins.Apps.Sms/),通过分析当前控制器就可以知道当前插件的View目录位置


using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Web; using System.Web.Mvc; using System.Web.WebPages.Razor; namespace Plugins.Web { public class CustomerViewEngine : RazorViewEngine { ///  /// 定义视图页所在地址。 ///  private string[] _viewLocatiOnFormats= new[] { "~/Views/Parts/{0}.cshtml", "~/Plugins/{pluginFolder}/Views/{1}/{0}.cshtml", "~/Plugins/{pluginFolder}/Views/Shared/{0}.cshtml", "~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml", }; public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) { string ns = controllerContext.Controller.GetType().Namespace; string cOntroller= controllerContext.Controller.GetType().Name.Replace("Controller", ""); //说明是插件中的控制器,View目录需要单独处理 if (ns.ToLower().Contains("plugins")) { var pluginsFolder = ns.ToLower().Replace(".controllers", ""); ViewLocatiOnFormats= ReplacePlaceholder(pluginsFolder); } return base.FindView(controllerContext, viewName, masterName, useCache); } ///  /// 替换pluginFolder占位符 ///  ///  private string[] ReplacePlaceholder(string folderName) { string[] tempArray = new string[_viewLocationFormats.Length]; if (_viewLocationFormats != null) { for (int i = 0; i <_viewLocationFormats.Length; i++) { tempArray[i] = _viewLocationFormats[i].Replace("{pluginFolder}", folderName); } } return tempArray; } } }

然后在主站点的Global.asax中将Razor引擎指定为我们重写过的

到此,一个插件系统的核心部分就算完成了,你可继续进行扩展,增加插件的发现、安装、卸载功能,这些相对于核心功能来说,都是小儿科。后续我会基于Abp框架出一个插件系统的文章,有兴趣的把小板凳准备好,瓜子花生买上:)

以上就是对ASP.NET中的MVC引擎开发插系统进行详解的详细内容,更多请关注其它相关文章!

内容推荐:免费高清PNG素材下载
吐了个 "CAO" !
扫码关注 PHP1 官方微信号
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved PHP1.CN 第一PHP社区 版权所有 京ICP备19059560号-4