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

  1. 转发-基于ASP.NET MVC 4/5 Razor的模块化/插件式架构实现

    基于ASP.NET MVC 4/5 Razor的模块化/插件式架构实现   概述 在日常开发中, 我们经常谈起模块化/插件化架构,这样可既可以提高开效率,又可以实现良好的扩展性,尤其对于产品化的系统有 ...

  2. 基于ASP.NET MVC 4/5 Razor的模块化/插件式架构实现

    概述 在日常开发中, 我们经常谈起模块化/插件化架构,这样可既可以提高开效率,又可以实现良好的扩展性,尤其对于产品化的系统有更好的实用性. 架构 我们采用的是MVC5(本文中介绍的方法对于MVC4也是 ...

  3. Android应用插件式开发解决方法

    转自:http://blog.csdn.net/arui319/article/details/8109650 一.现实需求描述 一般的,一个Android应用在开发到了一定阶段以后,功能模块将会越来 ...

  4. Android应用插件式开发解决方法[转]

    一.现实需求描述 一般的,一个Android应用在开发到了一定阶段以后,功能模块将会越来越多,APK安装包也越来越大,用户在使用过程中也没有办法选择性的加载自己需要的功能模块.此时可能就需要考虑如何分 ...

  5. ASP.NET MVC:模块化/插件式架构实现(转载)

    I’ve recently spent quite a lot of time researching and prototyping different ways to create a plugi ...

  6. ASP.NET MVC 4 插件化架构简单实现-思路篇

    用过和做过插件的都会了解插件的好处,园子里也有很多和讨论,但大都只些简单的加载程序集什么的,这里主要讨论的就是使用 ASP.NET MVC 4 来实现每个插件都可以完全从主站点剥离出来,即使只是一个插 ...

  7. MVC 4 插件化架构简单实现

    转ASP.NET MVC 4 插件化架构简单实现-思路篇   用过和做过插件的都会了解插件的好处,园子里也有很多和讨论,但大都只些简单的加载程序集什么的,这里主要讨论的就是使用 ASP.NET MVC ...

  8. ASP.NET MVC:模块化/插件式文章汇总

    方案 Shazwazza | Developing a plugin framework in ASP.NET MVC with medium trust 基于ASP.NET MVC3 Razor的模 ...

  9. Winfom 插件式(Plugins)/模块化开发框架-动态加载DLL窗体-Devexpress

    插件式(AddIn)架构,不是一个新名词,应用程序采用插件式拼合,可以更好的支持扩展.很多著名的软件都采用了插件式的架构,如常见的IDE:Eclipse,Visual Studio,SharpDeve ...

随机推荐

  1. WSARecv()

    简述:从一个套接口接收数据. #include <winsock2.h> int WSAAPI WSARecv ( SOCKET s, LPWSABUF lpBuffers, DWORD ...

  2. Jquery 校验文本框只能输入负数、小数、整数

     /*   umlzhang    date:2013-09-12   */   //检验只能输入整数,小数和负数    $(function () {          var obj = $(&q ...

  3. Js 基本数据类型、引用数据类型

    数据类型 1.   ECMAScript变量包含两种不同类型的值:基本类型值.引用类型值: 2.   基本类型值:指的是保存在栈内存中的简单数据段: 3.   引用类型值:指的是那些保存在堆内存中的对 ...

  4. vs2012 + web api + OData + EF + MYsql 开发及部署

    先说下我的情况,b/s开发这块已经很久没有搞了,什么web api .MVC.OData都只是听过,没有实际开发过,因为最近要开发一个手机app的服务端,所以准备用这套框架来开发. 下面开始进入正题( ...

  5. C++的优秀特性3:构造函数和析构函数

    (转载请注明原创于潘多拉盒子) 构造函数和析构函数是C++中再熟悉不过的概念了,几乎每个了解一点C++的人都知道这两个概念是什么意思.一个对象的全部生命期中构造函数和析构函数执行的时机如下: 1. 为 ...

  6. IE6中奇数宽高的BUG

    一个外部的相对定位div,内部一个绝对定位的div(right:0), 如图: 可是在IE6下查看,却变成了right:1px的效果了: IE6还有奇数宽高的bug,解决方案就是将外部相对定位的div ...

  7. Java多线程技术学习笔记(一)

    目录: 概述 多线程的好处与弊端 JVM中的多线程解析 多线程的创建方式之一:继承Thread类 线程的状态 多线程创建的方式之二:实现Runnable接口 使用方式二创建多线程的好处 多线程示例 线 ...

  8. linux scp 服务器远程拷贝

    一.将本机文件复制到远程服务器上 #scp /home/administrator/news.txt root@192.168.1.1:/etc/squid /home/administrator/  ...

  9. C#调用C++ dll时,结构体引用传参的方法

    写了一个C++的LogLog Logit 四参数等算法的接口dll,给C#调用,但是发现传参有问题 如 extern "C" _declspec(dllexport)  bool ...

  10. Timing advance of GSM(时间提前量)

    基本概念 时间提前量TA(Timing Advance)的作用是为了补偿电波传输延迟,而根本目的则是为了提高信道编解码效率.由于GSM采用TDMA,每载频8个时隙,应严格保持时隙间的同步,没有TA就无 ...