插件式架構,一種全新的、開放性的、高擴展性的架構體系.插件式架構設計近年來很是流行,基於插件的設計好處不少,把擴展功能從框架中剝離出來,下降了框架的複雜度,讓框架更容易實現。擴展功能與框架以一種很鬆的方式耦合,二者在保持接口不變的狀況下,能夠獨立變化和發佈。基於插件設計並不神祕,相反它比起一團泥的設計更簡單,更容易理解。下面已C# .Net簡要介紹一下插件式架構的方法.
定義插件接口,將其編譯成dll架構
namespace PluginInterface { public interface IPlugin { string Show(); } }
編寫插件,引用上面的DLL,實現上面定義的接口,也編譯爲DLL框架
//插件A namespace PluginA { public class PluginA:IPlugin { public string Show() { return "插件A"; } } } //插件B namespace PluginB { public class PluginB : IPlugin { public string Show() { return "插件B"; } } }
新建一個控制檯程序,須要引用定義插件接口的dll,生成以後,須要在exe所在的目錄裏建一個Plugins子文件夾,將上面生成的PluginA.dll,和PluginB.dll拷貝進去。
spa
namespace ConsolePluginTest { class Program { static void Main(string[] args) { Program p = new Program(); List<string> pluginpath = p.FindPlugin(); pluginpath = p.DeleteInvalidPlungin(pluginpath); foreach (string filename in pluginpath) { try { //獲取文件名 string asmfile = filename; string asmname = Path.GetFileNameWithoutExtension(asmfile); if (asmname != string.Empty) { // 利用反射,構造DLL文件的實例 Assembly asm = Assembly.LoadFile(asmfile); //利用反射,從程序集(DLL)中,提取類,並把此類實例化 Type[] t = asm.GetExportedTypes(); foreach (Type type in t) { if (type.GetInterface("IPlugin") != null) { IPlugin show = (IPlugin)Activator.CreateInstance(type); Console.Write(show.Show()); } } } } catch(Exception ex) { Console.Write(ex.Message); } } } //查找全部插件的路徑 private List<string> FindPlugin() { List<string> pluginpath = new List<string>(); try { //獲取程序的基目錄 string path = AppDomain.CurrentDomain.BaseDirectory; //合併路徑,指向插件所在目錄。 path = Path.Combine(path,"Plugins"); foreach (string filename in Directory.GetFiles(path, "*.dll")) { pluginpath.Add(filename); } } catch(Exception ex) { Console.Write(ex.Message); } return pluginpath; } //載入插件,在Assembly中查找類型 private object LoadObject(Assembly asm, string className, string interfacename , object[] param) { try { //取得className的類型 Type t =asm.GetType(className); if (t == null || !t.IsClass || !t.IsPublic || t.IsAbstract || t.GetInterface(interfacename) == null ) { return null; } //建立對象 Object o = Activator.CreateInstance(t,param); if (o == null) { //建立失敗,返回null return null; } return o; } catch { return null; } } //移除無效的的插件,返回正確的插件路徑列表,Invalid:無效的 private List<string> DeleteInvalidPlungin(List<string> PlunginPath) { string interfacename = typeof(IPlugin).FullName; List<string> rightPluginPath = new List<string>(); //遍歷全部插件。 foreach (string filename in PlunginPath) { try { Assembly asm = Assembly.LoadFile(filename); //遍歷導出插件的類。 foreach (Type t in asm.GetExportedTypes()) { //查找指定接口 Object plugin = LoadObject(asm,t.FullName,interfacename,null); //若是找到,將插件路徑添加到rightPluginPath列表裏,並結束循環。 if (plugin != null) { rightPluginPath.Add(filename); break; } } } catch { throw new Exception(filename+"不是有效插件"); } } return rightPluginPath; } } }