ASP.NET MVC 4 插件化架构简单实现-实例篇
2013-11-04 19:35
507 查看
先回顾一下上篇决定的做法:
1、定义程序集搜索目录(临时目录)。
2、将要使用的各种程序集(插件)复制到该目录。
3、加载临时目录中的程序集。
4、定义模板引擎的搜索路径。
5、在模板引擎的查找页面方法里,给指定插件的页面加上相应的程序集。
6、检测插件目录,有改变就自动重新加载。
--------------------------------------------我是分割线--------------------------------------------
先创建一个空的MVC4项目。
View Code
创建一个插件控制器工厂,来获得插件程序集中的控制器类型。
对 RazorViewEngine 的 FindPartialView 方法与 FindView 方法,根据插件来把该插件相关的程序集增加到 Razor 模板的编译项里。
关键代码:
到现在,该方法已经初步完成,现在就是把整个插件丢到插件目录下,重启就能加载了!
现在,就给它加上自动检测功能,FileSystemWatcher 类,设置当程序集发生修改、创建、删除和重命名时,自动重新加载插件。
把该方法进行注册:
又或者可以使用 System.Web.PreApplicationStartMethod 方法来启动(推荐)。
到这里,框架部分已经完成了!下面说下插件的开发。
1、创建一个空的 ASP.NET MVC 4 项目,并清理好。
2、定义一个实现 IPlugin 接口的类。
3、完成一个简单的页面显示功能。
将该插件站点发布。
将已发布的插件包含目录一起复制到站点的插件目录下即可。
完成了,现在不但可以把插件复制到插件目录就马上能使用,要调试什么的,也可以直接启动插件 WEB 项目了,具体的完善就不多说了!
不过,目前还有个小BUG,如果目录下没有任何插件的时候,插件检测将不会启动><。
注意!Views目录下必须要存在 Web.Config 文件,.NET 会根据该文件自动配置 cshtml 页面的基类等信息,假如没有该文件,编译页面时,会出现找不到基类错误。
源码:
点击下载
1、定义程序集搜索目录(临时目录)。
2、将要使用的各种程序集(插件)复制到该目录。
3、加载临时目录中的程序集。
4、定义模板引擎的搜索路径。
5、在模板引擎的查找页面方法里,给指定插件的页面加上相应的程序集。
6、检测插件目录,有改变就自动重新加载。
--------------------------------------------我是分割线--------------------------------------------
先创建一个空的MVC4项目。
namespace PluginMvc.Framework { using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Web.Hosting; /// <summary> /// 插件管理器。 /// </summary> public static class PluginManager { /// <summary> /// 插件字典。 /// </summary> private readonly static IDictionary<string, PluginDescriptor> _plugins = new Dictionary<string, PluginDescriptor>(); /// <summary> /// 初始化。 /// </summary> public static void Initialize() { //遍历所有插件描述。 foreach (var plugin in PluginLoader.Load()) { //卸载插件。 Unload(plugin); //初始化插件。 Initialize(plugin); } } /// <summary> /// 初始化插件。 /// </summary> /// <param name="pluginDescriptor">插件描述</param> private static void Initialize(PluginDescriptor pluginDescriptor) { //使用插件名称做为字典 KEY。 string key = pluginDescriptor.Plugin.Name; //不存在时才进行初始化。 if (!_plugins.ContainsKey(key)) { //初始化。 pluginDescriptor.Plugin.Initialize(); //增加到字典。 _plugins.Add(key, pluginDescriptor); } } /// <summary> /// 卸载。 /// </summary> public static void Unload() { //卸载所有插件。 foreach (var plugin in PluginLoader.Load()) { plugin.Plugin.Unload(); } //清空插件字典中的所有信息。 _plugins.Clear(); } /// <summary> /// 卸载。 /// </summary> public static void Unload(PluginDescriptor pluginDescriptor) { pluginDescriptor.Plugin.Unload(); _plugins.Remove(pluginDescriptor.Plugin.ToString()); } /// <summary> /// 获得当前系统所有插件描述。 /// </summary> /// <returns></returns> public static IEnumerable<PluginDescriptor> GetPlugins() { return _plugins.Select(m => m.Value).ToList(); } /// <summary> /// 根据插件名称获得插件描述。 /// </summary> /// <param name="name">插件名称。</param> /// <returns>插件描述。</returns> public static PluginDescriptor GetPlugin(string name) { return GetPlugins().SingleOrDefault(plugin => plugin.Plugin.Name == name); } } }
View Code
创建一个插件控制器工厂,来获得插件程序集中的控制器类型。
对 RazorViewEngine 的 FindPartialView 方法与 FindView 方法,根据插件来把该插件相关的程序集增加到 Razor 模板的编译项里。
关键代码:
/// <summary> /// 给运行时编译的页面加了引用程序集。 /// </summary> /// <param name="pluginName"></param> private void CodeGeneration(string pluginName) { RazorBuildProvider.CodeGenerationStarted += (object sender, EventArgs e) => { RazorBuildProvider provider = (RazorBuildProvider)sender; var plugin = PluginManager.GetPlugin(pluginName); if (plugin != null) { provider.AssemblyBuilder.AddAssemblyReference(plugin.Assembly); } }; }
到现在,该方法已经初步完成,现在就是把整个插件丢到插件目录下,重启就能加载了!
现在,就给它加上自动检测功能,FileSystemWatcher 类,设置当程序集发生修改、创建、删除和重命名时,自动重新加载插件。
namespace PluginMvc.Framework { using System.IO; using System.Web.Hosting; /// <summary> /// 插件检测器。 /// </summary> public static class PluginWatcher { /// <summary> /// 是否启用。 /// </summary> private static bool _enable = false; /// <summary> /// 侦听文件系统。 /// </summary> private static readonly FileSystemWatcher _fileSystemWatcher = new FileSystemWatcher(); static PluginWatcher() { _fileSystemWatcher.Path = HostingEnvironment.MapPath("~/Plugins"); _fileSystemWatcher.Filter = "*.dll"; _fileSystemWatcher.Changed += _fileSystemWatcher_Changed; _fileSystemWatcher.Created += _fileSystemWatcher_Created; _fileSystemWatcher.Deleted += _fileSystemWatcher_Deleted; _fileSystemWatcher.Renamed += _fileSystemWatcher_Renamed; _fileSystemWatcher.IncludeSubdirectories = true; Enable = false; } /// <summary> /// 是否启用。 /// </summary> public static bool Enable { get { return _enable; } set { _enable = value; _fileSystemWatcher.EnableRaisingEvents = _enable; } } /// <summary> /// 启动。 /// </summary> public static void Start() { Enable = true; } /// <summary> /// 停止。 /// </summary> public static void Stop() { Enable = false; } private static void _fileSystemWatcher_Changed(object sender, FileSystemEventArgs e) { ResetPlugin(); } private static void _fileSystemWatcher_Deleted(object sender, FileSystemEventArgs e) { ResetPlugin(); } private static void _fileSystemWatcher_Created(object sender, FileSystemEventArgs e) { ResetPlugin(); } private static void _fileSystemWatcher_Renamed(object sender, RenamedEventArgs e) { ResetPlugin(); } /// <summary> /// 重置插件。 /// </summary> private static void ResetPlugin() { PluginManager.Unload(); PluginManager.Initialize(); } } }
把该方法进行注册:
又或者可以使用 System.Web.PreApplicationStartMethod 方法来启动(推荐)。
[assembly: System.Web.PreApplicationStartMethod(typeof(PluginMvc.Framework.Bootstrapper), "Initialize")] namespace PluginMvc.Framework { using System.Web.Mvc; using PluginMvc.Framework; using PluginMvc.Framework.Mvc; /// <summary> /// 引导程序。 /// </summary> public static class Bootstrapper { /// <summary> /// 初始化。 /// </summary> public static void Initialize() { //注册插件控制器工厂。 ControllerBuilder.Current.SetControllerFactory(new PluginControllerFactory()); //注册插件模板引擎。 ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new PluginRazorViewEngine()); //初始化插件。 PluginManager.Initialize(); //启动插件检测器。 PluginWatcher.Start(); } } }
到这里,框架部分已经完成了!下面说下插件的开发。
1、创建一个空的 ASP.NET MVC 4 项目,并清理好。
2、定义一个实现 IPlugin 接口的类。
3、完成一个简单的页面显示功能。
将该插件站点发布。
将已发布的插件包含目录一起复制到站点的插件目录下即可。
完成了,现在不但可以把插件复制到插件目录就马上能使用,要调试什么的,也可以直接启动插件 WEB 项目了,具体的完善就不多说了!
不过,目前还有个小BUG,如果目录下没有任何插件的时候,插件检测将不会启动><。
注意!Views目录下必须要存在 Web.Config 文件,.NET 会根据该文件自动配置 cshtml 页面的基类等信息,假如没有该文件,编译页面时,会出现找不到基类错误。
源码:
点击下载
ASP.NET MVC 4 插件化架构简单实现-思路篇
ASP.NET MVC 4 插件化架构简单实现-实例篇
相关文章推荐
- ASP.NET MVC 4 插件化架构简单实现-实例篇
- ASP.NET MVC 4 插件化架构简单实现-思路篇
- ASP.NET MVC 4 插件化架构简单实现-思路篇
- ASP.NET MVC 4 插件化架构简单实现-思路篇
- ASP.NET MVC 4 插件化架构简单实现-思路篇
- ASP.NET MVC 4 插件化架构简单实现-思路篇
- ASP.NET MVC 4 插件化架构简单实现-思路篇
- ASP.NET MVC 4 插件化架构简单实现-实例篇
- MVC 4 插件化架构简单实现实例篇
- asp.net mvc中自行搭建实现工厂模式的spring.net+三层架构 (15-4-20)
- ASP.NET MVC 3 Model【通过一简单实例一步一步的介绍】
- ASP.NET Core Web API下事件驱动型架构的实现(一):一个简单的实现
- MVC架构在Asp.net中的应用和实现
- ASP.NET MVC 入门10、Action Filter 与 内置的Filter实现(实例-防盗链)
- asp.net mvc简单分页实例
- asp.net mvc实现简单的实时消息推送
- ASP.NET MVC 3 Model【通过一简单实例一步一步的介绍】
- ASP.NET MVC 入门10、Action Filter 与 内置的Filter实现(实例-防盗链)
- ASP.NET MVC 3 Model【通过一简单实例一步一步的介绍】【续Model验证部分】
- ASP.NET MVC 中使用Spring.NET实现简单的属性注入