简单的c#插件框架
插件式架构,一种全新的、开放性的、高扩展性的架构体系.插件式架构设计近年来非常流行,基于插件的设计好处很多,把扩展功能从框架中剥离出来,降低了框架的复杂度,让框架更容易实现。扩展功能与框架以一种很松的方式耦合,两者在保持接口不变的情况下,可以独立变化和发布。基于插件设计并不神秘,相反它比起一团泥的设计更简单,更容易理解。下面已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;
}
}
}
简单的c#插件框架的更多相关文章
- 分享在Linux下使用OSGi.NET插件框架快速实现一个分布式服务集群的方法
在这篇文章我分享了如何使用分层与模块化的方法来设计一个分布式服务集群.这个分布式服务集群是基于DynamicProxy.WCF和OSGi.NET插件框架实现的.我将从设计思路.目标和实现三方面来描述. ...
- 【UI插件】简单的日历插件(下)—— 学习MVC思想
前言 我们上次写了一个简单的日历插件,但是只是一个半成品,而且做完后发现一些问题,于是我们今天尝试来解决这些问题 PS:距离上次貌似很久了 上次,我们大概遇到哪些问题呢: ① 既然想做一套UI库,那么 ...
- 动端逐渐出了许多的移动端的框架,比如Sencha Touch、JQTouch、Jquery-moblie、jqMobi等等。这些框架都有优缺点,不同的框架应用在不同的项目中。现简单阐述一下各框架的优缺点:
移动前端工作的那些事---前端制作之微信小技巧篇 (2013-11-15 15:20) 转载▼ 标签: it css3/javascript html5 webapp 手机网站搭建 分类: 前端制 ...
- 终于可以发布Delphi下收点OSGI精髓皮毛而设计的插件框架WisdomPluginFramework
这是一个Delphi实现的插件框架,我耗费了相当相当相当多的精力来设计她,虽然仅闪着点我微薄智慧的光芒,但我还是决定用Wisdom来命名她,也因它是我绝无仅有的,在完成1年多后回头来看仍能相当满意的作 ...
- 基于Proxy思想的Android插件框架
意义 研究插件框架的意义在于下面几点: 减小安装包的体积,通过网络选择性地进行插件下发 模块化升级.减小网络流量 静默升级,用户无感知情况下进行升级 解决低版本号机型方法数超限导致无法安装的问题 代码 ...
- [转]C/C++:构建你自己的插件框架
本文译自Gigi Sayfan在DDJ上的专栏文章.Gigi Sayfan是北加州的一个程序员,email:gigi@gmail.com. 本文是一系列讨论架构.开发和部署C/C++跨平台插件框架的文 ...
- 在ASP.NET MVC应用中开发插件框架(中英对照)
[原文] Developing a plugin framework in ASP.NET MVC with medium trust [译文] 在ASP.NET MVC应用中开发一个插件框架 I’v ...
- .Net中的插件框架Managed Extensibility Framework
Managed Extensibility Framework(MEF)是微软的一个用来扩展.NET应用程序的框架,它最初为了满足Visual Studio里的编辑器的需求,比如说,延迟加载所有东西和 ...
- Delphi 的插件框架 WisdomPluginFramework
WisdomPluginFramework是融合OSGI微内核理念 + Eclipse的扩展点概念而精心设计的轻量级插件框架, 由Delphi实现,但可以使用于Delphi.BCB.VC++中,提供非 ...
随机推荐
- suse11 sp2 搭建openvpn
什么是VPN IP机制仿真出一个私有的广域网"是通过私有的隧道技术在公共数据网络上仿真一条点到点的专线技术.所谓虚拟,是指用户不再需要拥有实际的长途数据线路,而是使用Internet公众数据 ...
- radio选中
设置选中:$(':radio[name=isnode][value=' + isnode + ']').prop('checked',true); 1.获取选中值,三种方法都可以: $('input: ...
- JavaScript高级程序设计学习笔记--引用类型
Object类型 对象字面量表示法: var person={ name:"Nicholas", age:29, 5:true }; 这人例子会创建一个对象,包含三个属性:name ...
- EL表达式中fn函数 (转载)
JSTL 使用表达式来简化页面的代码,这对一些标准的方法,例如bean的getter/setter方法,请求参数或者context以及 session中的数据的访问非常方便,但是我们在实际应用中经常需 ...
- Memcache使用
//需要下载memcache 服务 然后 在命令里面 安装和启动服务 //引用 Memcached.ClientLibrary.dllpublic class MemcacheHelper { pub ...
- 【leetcode】Jump Game I & II (hard)
Jump Game (middle) Given an array of non-negative integers, you are initially positioned at the firs ...
- IOS - socket 编程初体验
#import "ViewController.h" @interface ViewController () <NSStreamDelegate, UITextFieldD ...
- Linux Shell多命令执行
有三种: :只是顺序执行,命令之间没有任何关联,不相互影响.如 ls;date;cd /etc/ 如,创建100M的文件. && 命令之间有关系,只有前一条命令正确执行才会执行下面一 ...
- SQL 映射的 XML 文件
MyBatis 真正的力量是在映射语句中.这里是奇迹发生的地方. 对于所有的力量, SQL映射的 XML 文件是相当的简单.当然如果你将它们和对等功能的 JDBC 代码来比较,你会发现映射文件节省了大 ...
- python 取两数的百分比
Python (r266:, Jan , ::) [GCC (Red Hat -)] on linux2 Type "help", "copyright", & ...