概述
nopCommerce的插件机制的核心是使用BuildManager.AddReferencedAssembly将使用Assembly.Load加载的插件程序集添加到应用程序域的引用中。具体实现可以参考nopCommerce解决方案中Nop.Core项目的Plugins目录下的相关文件。其中PluginManager.cs文件是核心文件,包含了处理插件化的核心代码。nopCommerce的注释中感谢了其参考的Umbraco项目,并给出了主要参考文章的链接。
我们直接从nopCommerce3.5的实现中抽取必要的实现代码,制作一个简易版的插件系统Demo用于演示ASP.NET MVC的插件化,核心只包含一个标记接口IPlugin,一个管理类PluginManager包含2个必要方法Initialize和ReStart。
架构
新建.NET解决方案SimplePlugin,添加2个类库项目:SimplePlugin.PluginCore、SimplePlugin.SimpleMvcPlugin和一个ASP.NET应用程序项目SimplePlugin.Web。SimplePlugin.Web项目选择Empty模板并选中MVC引用。设置项目之间的依赖关系和程序集引用:向SimplePlugin.SimpleMvcPlugin添加SimplePlugin.PluginCore项目引用,向SimplePlugin.Web项目添加SimplePlugin.PluginCore项目引用。向SimplePlugin.PluginCore项目添加System.Web引用。
![](https://images0.cnblogs.com/blog2015/194803/201503/142210221994730.jpg)
1.约定
(1)约定"~/Plugins"作为插件根目录。
(2)约定"~/Plugins/bin"作为中等信任级别下的运行时目录。
插件在运行时加载的是插件程序集在运行时目录的副本,不直接加载插件而是加载运行时目录中的副本的原因是避免插件升级或删除时dll文件被锁定。2.基础代码
向SimplePlugin.PluginCore项目添加如下文件:
(1)IPlugin.cs:作为所有插件的抽象接口。
![](https://images0.cnblogs.com/blog2015/194803/201503/142212548551502.jpg)
(2)PluginManager:负责加载插件和引用插件。
![](https://images0.cnblogs.com/blog2015/194803/201503/142213248392194.jpg)
(3)向Simple.Web项目添加Plugins目录和Plugins/bin目录。向Simple.Web项目添加Controllers/PluginController.cs
![](https://images0.cnblogs.com/blog2015/194803/201503/142214027143465.jpg)
修改web.config,配置probing元素。指定trust level为中等信任级别下的插件运行时目录。
![](https://images0.cnblogs.com/blog2015/194803/201503/142214334808731.jpg)
3.编写插件
通过Nuget向SimplePlugin.SimpleMvcPlugin项目添加MVC程序集引用,需要注意插件的MVC版本与SimplePlugin.PluginCore引用的MVC版本的一致性。
(1)添加Controllers/SimpleMvcPlugin.cs实现接口IPlugin
![](https://images0.cnblogs.com/blog2015/194803/201503/142215002618080.jpg)
(2)添加Controllers/SimplePluginMvcController.cs
![](https://images0.cnblogs.com/blog2015/194803/201503/142215193082366.jpg)
(2)添加视图Views/SimpleMvcPlugin/Index.cshtml
![](https://images0.cnblogs.com/blog2015/194803/201503/142215415748467.jpg)
(3)复制SimplePlugin.Web项目中SimplePlugin.Web/Views/web.config文件到当前项目的根目录和Views目录下。
(4)设置.cshtml以及.config文件类型为内容,生成设置为较新则复制。
![](https://images0.cnblogs.com/blog2015/194803/201503/142216157617080.jpg)
(5)设置SimplePlugin.SimpleMvcPlugin项目引用的程序集属性复制到本地为False。
(6)设置SimplePlugin.SimpleMvcPlugin项目的生成路径为binDebugSimpleMvcPlugin和binReleaseSimpleMvcPlugin
4.手动部署插件
生成解决方案,访问SimplePlugin.Web的插件列表页:
![](https://images0.cnblogs.com/blog2015/194803/201503/142216577148595.jpg)
拷贝生成的SimpleMvcPlugin文件夹到SimplePlugin.Web项目的Plugins文件夹下,访问SimplePlugin.Web的~/Plugin/Install访问SimplePlugin.Web的插件列表页
![](https://images0.cnblogs.com/blog2015/194803/201503/142217223088543.jpg)
访问SimplePlugin.Web的~/SimpleMvcPlugin/Index页
![](https://images0.cnblogs.com/blog2015/194803/201503/142217390748698.jpg)
5.自动部署
设置设置SimplePlugin.SimpleMvcPlugin项目的生成路径为:..SimplePlugin.WebPluginsSimpleMvcPlugin 同时设置Debug和Release两种配置。
![](https://images0.cnblogs.com/blog2015/194803/201503/142218042146044.jpg)
重新生成解决方案,访问SimplePlugin.Web的插件列表页以及~/SimpleMvcPlugin/Index页:
![](https://images0.cnblogs.com/blog2015/194803/201503/142218322929122.jpg)
![](https://images0.cnblogs.com/blog2015/194803/201503/142218480588807.jpg)
6.测试中级信任级别
设置web.config的trust元素的level属性为Medium,禁止访问应用程序目录以外的文件。
![](https://images0.cnblogs.com/blog2015/194803/201503/142219098394593.jpg)
重新生成解决方案,访问SimplePlugin.Web的插件列表页以及~/SimpleMvcPlugin/Index页。检查Plugins/bin目录:
![]()
![](https://images0.cnblogs.com/blog2015/194803/201503/142219324333197.jpg)
7.测试视图文件修改
修改SimplePlugin.Web项目PluginsSimpleMvcPluginViewsSimpleMvcPlugin目录下的Index.cshtml。查看修改结果:
![](https://images0.cnblogs.com/blog2015/194803/201503/142220034179062.jpg)