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#实现插件式架构的方法的更多相关文章
- 转发-基于ASP.NET MVC 4/5 Razor的模块化/插件式架构实现
基于ASP.NET MVC 4/5 Razor的模块化/插件式架构实现 概述 在日常开发中, 我们经常谈起模块化/插件化架构,这样可既可以提高开效率,又可以实现良好的扩展性,尤其对于产品化的系统有 ...
- 基于ASP.NET MVC 4/5 Razor的模块化/插件式架构实现
概述 在日常开发中, 我们经常谈起模块化/插件化架构,这样可既可以提高开效率,又可以实现良好的扩展性,尤其对于产品化的系统有更好的实用性. 架构 我们采用的是MVC5(本文中介绍的方法对于MVC4也是 ...
- Android应用插件式开发解决方法
转自:http://blog.csdn.net/arui319/article/details/8109650 一.现实需求描述 一般的,一个Android应用在开发到了一定阶段以后,功能模块将会越来 ...
- Android应用插件式开发解决方法[转]
一.现实需求描述 一般的,一个Android应用在开发到了一定阶段以后,功能模块将会越来越多,APK安装包也越来越大,用户在使用过程中也没有办法选择性的加载自己需要的功能模块.此时可能就需要考虑如何分 ...
- ASP.NET MVC:模块化/插件式架构实现(转载)
I’ve recently spent quite a lot of time researching and prototyping different ways to create a plugi ...
- ASP.NET MVC 4 插件化架构简单实现-思路篇
用过和做过插件的都会了解插件的好处,园子里也有很多和讨论,但大都只些简单的加载程序集什么的,这里主要讨论的就是使用 ASP.NET MVC 4 来实现每个插件都可以完全从主站点剥离出来,即使只是一个插 ...
- MVC 4 插件化架构简单实现
转ASP.NET MVC 4 插件化架构简单实现-思路篇 用过和做过插件的都会了解插件的好处,园子里也有很多和讨论,但大都只些简单的加载程序集什么的,这里主要讨论的就是使用 ASP.NET MVC ...
- ASP.NET MVC:模块化/插件式文章汇总
方案 Shazwazza | Developing a plugin framework in ASP.NET MVC with medium trust 基于ASP.NET MVC3 Razor的模 ...
- Winfom 插件式(Plugins)/模块化开发框架-动态加载DLL窗体-Devexpress
插件式(AddIn)架构,不是一个新名词,应用程序采用插件式拼合,可以更好的支持扩展.很多著名的软件都采用了插件式的架构,如常见的IDE:Eclipse,Visual Studio,SharpDeve ...
随机推荐
- global & nonlocal
name = "A" def test(): name = "B" def test2(): global name # global 指的是拿到的是全局的变量 ...
- UVaLive 7512 November 11th (思维漏洞)
题意:给定n*m个座椅,然后有b个是坏的,要做人,并且两个人不能相邻,问你最多坐多少人,最少坐多少人. 析:这个题其实并不难,只要当时一时没想清楚,结果就一直WA,就是最少的情况时,其实一个人可以占三 ...
- NS_ENUM & NS_OPTIONS
When everything is an object, nothing is. So, there are a few ways you could parse that, but for the ...
- 规范打log
在公司工作快3年了,debug用的最多的还是分析程序打出来的log. 怎样打log,打什么样的log,也是很值得研究的事情.好的打log方式,能够很快的分析和解决问题. 下面总结两点: 1.在log中 ...
- Android vector标签 PathData 画图超详解
SVG是一种矢量图格式,是Scalable Vector Graphics三个单词的首字母缩写.在xml文件中的标签是<vector>,画出的图形可以像一般的图片资源使用,例子如下: &l ...
- 新建VM_Script
在Hyper-V群集中,不需要设置VM的自启动,当宿主机意外关机重新启动后,上面的VM会自动转移到另一台主机:如果另一台主机处于关机状态,则宿主机重新启动后,其VM也会自启动(如果其VM在宿主机关机前 ...
- RDD的依赖关系
RDD的依赖关系 Rdd之间的依赖关系通过rdd中的getDependencies来进行表示, 在提交job后,会通过在DAGShuduler.submitStage-->getMissingP ...
- 博客标题栏增加一个"闪存“按钮
最近来博客园喜欢去闪存上看看,也就是一个类似微博的东西,但是貌似没看到哪里有这个按钮. 所以只要自己动手搞一个. 暴力猴js: // ==UserScript== // @name fwindpeak ...
- ORCALE用户授权与创建同义词
创建同义词: DROP public synonym marketmonitor_day; DROP public synonym marketmonitor_month; DROP public s ...
- [NOIP 2014复习]第三章:动态规划——NOIP历届真题回想
背包型动态规划 1.Wikioi 1047 邮票面值设计 题目描写叙述 Description 给定一个信封,最多仅仅同意粘贴N张邮票,计算在给定K(N+K≤40)种邮票的情况下(假定全部的邮票数量都 ...