一、概述
在前面的文章中系统的介绍过MEF技术,我们知道通过MEF可以很容易的实现应用程序的扩展。那么除了MEF之外应该还有很多技术可以实现应用程序的扩展(毕竟MEF是随着.net4.0一起发布的)。本文就简单的介绍下其中一种扩展技术:【插件架构】,分为上、下两篇,上篇介绍基本概念,下篇为应用篇。由于插件架构在winform中应用较为广泛,因此本文的写作目的是使用插件架构搭建一个简单的winform程序。
二、插件与插件架构(或者叫“插件机制”)
1.插件
日常,我们使用各种软件(特别是使用VS)时,可以安装很多的插件。那插件(plug-in)是什么呢?先介绍一个概念:宿主(host),顾名思义就是程序寄宿或挂载对象。有了宿主我们就可以定义插件了:符合指定宿主某种接口,并能够提供特定功能的程序。(个人观点)
2.插件架构
一时也没有想到什么好的语句来定义插件架构,但是可以这样描述它:插件架构是这样一种的设计,它降低了宿主与具体的应用模块的依赖,对于宿主来说,它不再关心每一个具体的插件如何实现,只要该插件满足宿主的规范,那么宿主就能够加载它。 相反,作为插件,它只要满足了宿主的规范便可被宿主加载。这样设计出来的程序具有很强的扩展性。
使用插件架构时一般都会使用到反射(reflector)。
三、示例
在上面的描述中我们提到了插件需要满足宿主的某种规范。这种规范在实际编码中便体现成Interface或者abstract class。
1.我们定义一个接口如下:
1 /// <summary> 2 /// 插件应遵循的接口 3 /// </summary> 4 public interface IPlugIn 5 { 6 void Show(); 7 }
2.定义一个插件,需要实现上述接口:
1 /// <summary> 2 /// 具体插件 3 /// </summary> 4 public class MyPlugIn : IPlugIn 5 { 6 7 8 #region IPlugIn 成员 9 10 public void Show() 11 { 12 Console.WriteLine("This is my PlugIn!"); 13 } 14 15 #endregion 16 }
3.重点来了,我们这里定义一个宿主,并利用反射创建具体插件的实例:
1 public class PlugInHost 2 { 3 /// <summary> 4 /// 加载所有的插件 5 /// </summary> 6 /// <returns></returns> 7 public List<IPlugIn> LoadPlugIns() 8 { 9 List<IPlugIn> plugList = new List<IPlugIn>(); 10 Assembly pluginAssembly = null; 11 string path = System.IO.Directory.GetCurrentDirectory() + "/plugins/MyPlugin.dll"; 12 try 13 { 14 //加载程序集 15 pluginAssembly = Assembly.LoadFile(path); 16 } 17 catch(Exception ex) 18 { 19 Console.WriteLine(ex.Message); 20 return plugList; 21 } 22 Type[] types = pluginAssembly.GetTypes(); 23 foreach (Type type in types) 24 { 25 if (type.GetInterface("IPlugIn") != null) 26 { 27 //创建插件的实例 28 plugList.Add((IPlugIn)Activator.CreateInstance(type)); 29 } 30 } 31 return plugList; 32 33 } 34 }
4.定义完了插件、扩展规则、宿主之后我们来尝试调用:
1 static void Main(string[] args) 2 { 3 PlugInHost host = new PlugInHost(); 4 var plugins = host.LoadPlugIns(); 5 foreach (var plugin in plugins) 6 { 7 plugin.Show(); 8 } 9 10 Console.Read(); 11 } 12 }
看下运行结果:
到此我们制作了一个简单的基于插件架构的程序,我可以看一下项目结构:
在上述解决方案中,引用关系为:Host引用AppContex,MyPlugIn引用AppContex。这样就把Host和具体PlugIn隔离开了,减少了依赖,方便我们队应用程序的扩展。
当然实际应用中的插件架构要比上面这个例子复杂很多。其中还要涉及到插件和宿主的交互,插件之间的交互。在下一篇文章中,我们将具体介绍插件架构在Winform程序中的应用,将涉及到插件同宿主、插件同插件之间的交互,