大雀软件园

首页 软件下载 安卓市场 苹果市场 电脑游戏 安卓游戏 文章资讯 驱动下载
技术开发 网页设计 图形图象 数据库 网络媒体 网络安全 站长CLUB 操作系统 媒体动画 安卓相关
当前位置: 首页 -> 技术开发 -> NET专区 -> C#插件构架实战

C#插件构架实战

时间: 2021-07-31 作者:daque

c# 插件构架实战 jack h hansen [ 2004-07-27 ] keywords c# 插件 曲射(system.reflection) 属性(system.attribute) 一、弁言 1. 题目的引入 假如你安排的步调仍旧安置到用户的计划机上,而且不妨平常运转了。然而有一天,用户打来了电话——她们诉求减少新的功效。决定了用户的需要后,你果然创造原有的软硬件框架结构仍旧没辙独当一面新增工作的需要——你须要从新安排这个运用了!但题目是,就算你又用了一个开拓周期实行了用户须要的运用,却不许保护用户的需要不会再次变换。也即是说,需要曼延的大概性仍旧生存。所以,这种情景下插件构架更能表露出它的出色性。 2. 几个处置计划的比较 我归纳了一下我所交战到的插件构架,大概上可分为以次几类: i> 剧本式 运用那种谈话把插件的步调论理写成剧本代码。而这种谈话不妨是 python ,或是其余现存的仍旧过程用户长功夫检验的剧本谈话。以至,你不妨自行安排一种剧本谈话来共同你步调的特出须要。固然,用现在最时髦的 xml 是再符合然而了。 这种情势的特性在乎,稍有点编制程序常识的用户就不妨自行窜改你的剧本( ^_^ 假设你不加密它的话)。咱们没辙论据这是长处仍旧缺点。由于,这种情景所形成的成果是不行先见的。 ii> 动静因变量库 dll 插件功效以动静库因变量的情势生存。主步调经过那种渠道(插件编写者或某些东西)赢得插件 dll 中的因变量出面,而后在符合的场合挪用它们。用过 matlab 的读者群都领会, matlab 中的各项功效简直都是些动静链入的因变量。 iii> 会合式 望文生义,即是把插件功效径直写成 exe 。主步调除去实行本人的工作外,还控制安排那些“插件”。我不爱好这种情势。这使插件与插件之间,主步调与插件之间(主假如这一点)的消息交谈艰巨了很多。巴比伦塔的波折 [1] 从那种水平上讲即是消息交谈没辙实行形成的。 iv> com 组件 com [2] 的爆发给这个寰球填补了几分生机。惟有接口!咱们的插件须要做的不过实行步调设置的接口。主步调不须要领会插件还好吗实行预订的功效,它只须要经过接口考察插件,并供给主步调关系东西的接口。如许一来,主步调与各插件之间的消息交谈就变得特殊大略。而且,插件对于主步调来说是实足通明的。 3. 计划 c# 是面向东西的步调安排谈话。它供给了 interface 要害字来径直设置接口。同声, system.reflection 定名空间也供给了考察外部步调集的一系列关系东西。这就为咱们在 c# 中实行插件构架打下了坚忍的普通。 底下,咱们将以一个具备插件构架的步调编纂器为例,来阐明这种构架在 c# 中的实行。 二、安排进程 好了,此刻咱们筹备把一切的中心代码都放在 cspluginkernel 定名空间中。用vside创造一个c#类库工程。在定名空间 cspluginkernel 中发端咱们的代码。 1. 接口安排 咱们的步调编纂器会向插件盛开正在编纂的文书档案东西。步调启用后,就列举每一个插件并把它贯穿到主步调,同声传播主步调东西的接口。插件不妨经过这个接口来乞求主步调东西或考察主步调功效 。 按照上头的需要,咱们开始须要一个主步调接口: public interface iapplicationobject { void alert( string msg ); // 爆发一条消息 void showinstatusbar( string msg ); // 将指定的消息表露在状况栏 idocumentobject querycurrentdocument(); // 获得暂时运用的文书档案东西 idocumentobject[] querydocuments(); // 获得一切的文书档案东西 // 树立事变处置器 void setdelegate( delegates whichone , eventhandler targer ); } // 暂时只须要这一个事变 public enum delegates { delegate_activedocumentchanged , } 而后是 idocumentobject 接口。插件经过这个接口考察编纂器东西。 /// /// 编纂器东西必需实行这个接口 /// public interface idocumentobject { // 那些属性是 richtextbox 控件的相映的属性映照 string selectiontext { get ; set ; } color selectioncolor { get ; set ; } font selectionfont { get ; set ; } int selectionstart { get ; set ; } int selectionlength { get ; set ; } string selectionrtf { get ; set ; } bool haschanges { get ; } void select( int start , int length ); void appendtext( string str ); void savefile( string filename ); void savefile(); void openfile( string filename ); void closefile(); } 这个接口不须要过多证明。这边我只实行了richtextbox控件少量的几个本领,其余大概用获得的,读者群自行增添即可。 再而后,按照插件在其人命周期里的动作,安排插件的接口。 /// /// 本步调的插件必需实行这个接口 /// public interface iplugin { connectionresult connect( iapplicationobject app ); void ondestory(); void onload(); void run(); } /// /// 表白插件与主步调贯穿的截止 /// public enum connectionresult { connection_success , connection_failed } 主步调会开始挪用 connect() 本领,并传播 iapplicationobject 给插件。插件在这个进程中做少许初始化处事。而后,插件的 onload() 本领被挪用。在这之后,当主步调接受到挪用插件的旗号时(键盘、鼠标相应)就会挪用插件的 run() 本领来启用这个插件。步调中断时,挪用其 ondestory() 本领。如许,插件的人命才颁布中断。 2. 插件消息的保存与获得 一个插件须要有它的称呼 、本子等消息。动作安排者的你,也确定要留住你的尊姓学名和部分网站等用来传播本人。 c# 的新个性——属性, 即是一个很好的处置计划。所以咱们设置一个从 system.attribute 接受来的类 plugininfoarrtibute :/// /// 用来指定一个插件的关系消息 /// public class plugininfoattribute : system.attribute { /// /// deprecated. do not use. /// public plugininfoattribute() {} public plugininfoattribute( string name , string version , string author , string webpage , bool loadwhenstart ) { // 详细已略去 } public string name { get { return _name; } } public string version { get { return _version; } } public string author { get { return _author; } } public string webpage { get { return _webpage; } } public bool loadwhenstart { get { return _loadwhenstart; } } /// /// 用来保存少许有效的消息 /// public object tag { get { return _tag; } set { _tag = value ; } } /// /// 用来保存序号 /// public int index { get { return _index; } set { _index = value ; } } private string _name = ""; private string _version = ""; private string _author = ""; private string _webpage = ""; private object _tag = null ; private int _index = 0; // 姑且不会用 private bool _loadwhenstart = true ; } 用这个类化装你的插件,并让他实行 iplugin 接口:/// /// my pluging 1( just for test ) /// [ plugininfo( "my pluging 1( just for test )" , "1.0" , "jack h hansen" , "http://blog.csdn.net/matrix2003b" , true )] public class myplugin1 : iplugin { public myplugin1() { } #region iplugin 分子 // 详细已略去 #endregion private iapplicationobject _app; private idocumentobject _curdoc; } 3. 加载插件 此刻就得用到 system.refelction 定名空间了。步调在启用时会探求 plugins 目次下的每一个文献。对于每一个文献,即使它是一个插件,就用 assembly 东西加载它。而后列举步调会合的每一个东西。确定一个步调集能否为咱们的插件的本领是确定它能否径直或转弯抹角实行自 iplugin。用底下的因变量,传播从步调集列举的东西的system.type。private bool isvalidplugin( type t ) { bool ret = false ; type[] interfaces = t.getinterfaces(); foreach ( type theinterface in interfaces ) { if ( theinterface.fullname == "cspluginkernel.iplugin" ) { ret = true ; break ; } } return ret; } 若前提都满意,isvalidplugin() 就会归来 true 。接着步调就会创造这个东西并把它存于一个 arraylist 中。plugins.add( pluginassembly.createinstance( plugingtype.fullname ) ); 此刻,你就不妨撰写尝试代码了。三、源代码 因为篇幅所限,完备的源代码(包括尝试用例)请在底下的链接载入。载入后请用 vs.net2003 翻开,从新天生处置计划即可(须要 .net framework 1.1)。尝试用例是一个在 richtextbox 控件里插入赤色文本的插件。很大略,只作尝试之用。四、结束语 that's all! 有了这种插件构架,不幸的步调员们就再也不必为需要曼延奢侈心术了。其余,欢送对正文以及正文的附加代码作出评介。再有,即是,常去我的 blog 看看~~ ^_^注:[1] 巴比伦塔的波折 《人月传奇》,frederick p. brooks jr. 第 7 章 干什么巴比伦塔会波折 [2] com 相关 com/com+ 的精细本领详细请拜见《 mastering com and com+ 》 , ash rofail , yasser shohoud.

热门阅览

最新排行

Copyright © 2019-2021 大雀软件园(www.daque.cn) All Rights Reserved.