插件式架构,一种全新的、开放性的、高扩展性的架构体系.插件式架构设计近年来非常流行,基于插件的设计好处很多,把扩展功能从框架中剥离出来,降低了框架的复杂度,让框架更容易实现。扩展功能与框架以一种很松的方式耦合,两者在保持接口不变的情况下,可以独立变化和发布。基于插件设计并不神秘,相反它比起一团泥的设计更简单,更容易理解。下面已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拷贝进去。

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;
}
}
}

最新文章

  1. spring hibernate4 c3p0连接池配置
  2. arcgis for flex或silverlight全国地图天气预报的实现
  3. CSS3系列三(与背景边框相关样式 、变形处理、动画效果)
  4. APK软件反编译 去广告
  5. golang学习遭遇错误原因分析续
  6. Android(java)学习笔记146:Bundle和Intent类使用和交互
  7. Spring实例化bean的三种方法
  8. 2016-05-I
  9. MVC 4.0语法 自动分页
  10. jquery模拟checkbox效果,以及background-size在jquery中的使用。
  11. C语言基础04
  12. VS2012 内容存储区指定的位置无效或者您无权访错误
  13. SQL SERVER IN参数化处理
  14. Spark Standalone模式应用程序开发
  15. 【贪心】时空定位I
  16. TOE(TCP/IP Offload Engine)网卡与一般网卡的区别
  17. Python自定义异常及抛出异常
  18. CentOS 7下安装Python3.6.4
  19. url的反向解析
  20. java面试资源(面试题、面试经验等)

热门文章

  1. poj 3216 Repairing Company(最短路Floyd + 最小路径覆盖 + 构图)
  2. ACM之最短路径做题笔记与记录
  3. 关于IE开发人员工具(F12)找不到的问题
  4. Java调用Telnet示例
  5. 动态调用WebService(C#)
  6. springmvc中forward和redirect
  7. 为什么iphone手机比android手机流畅
  8. C#读写者线程(用AutoResetEvent实现同步)
  9. 10 款精美的 CSS3 全新特效
  10. QML学习笔记之一