今日看点

闲谈可插拔式应用程序的开发

发表于话题:闲淡抄人
发布时间:2021-06-01

    很多软件都是可插拔的,最知名的便是微软的Windows操作系统。你可以在Windows操作系统上安装QQ,也可卸掉QQ,这便是可插拔。这里不谈Windows的实现,因为太过复杂。本文就谈谈管理软件的可插拔的实现。相对Windows操作系统,QQ就是它的一个插件。所以可以简单的将开发可插拔的软件分为两个部分。一个是主应用程序的开发,一个是插件的开发。

    比Windows小的,常见的可插拔的软件是MSN。MSN主应用程序由MS开发,还存在一些MSN插件开发商,国内好像也有不少,这些插件开发商通过在插件中植入广告获取利润。MS不可能提高源代码给这些开发商,那么MSN的主应用程序和MSN的插件是如何衔接起来的呢。我想应该是MS提供了一些接口和方法供开发商使用,估计有个api之类的东西,所以开发可插拔的应用系统分为三个部分。

1、主应用程序的开发

2、公用接口的开发

3、插件的开发

    了解了这些以后,下面通过一个实例来说明。这个实例的原则是可扩展性强,能向下兼用。

    业务需求是:老系统每当逢年过节的时候,会通过邮件给用户发送一些祝福的邮件。现在流行手机和MSN(QQ没有借口)之后,客户希望系统能通过手机短信和MSN的消息给用户送去祝福。现在我们需要开发手机短信和MSN留言两个插件,然后将它们安装到系统中去。

实现:

    为了简单起见,这里使用控制台应用程序,如果你有兴趣,可以修改成asp.net或者Windows Form的。

    定义两个接口:

public interface IPluginHost { void AddMenuItem(string name, MenuItemClickedHandler clickHandler); void RegisterComponent(T component) where T : class; void MailNotice(string messaage); } public delegate void MenuItemClickedHandler(string name);

 

这个接口是主应用程序继承的,现在只有MailNotice功能, AddMenuItem是供插件调用的方法,创建一个菜单。RegisterComponent是插件向主应用程序提供一些方法。 public interface IPlugin { void Initialize(IPluginHost pluginHost); void DoSomething(); }

    上面是插件的接口。

    在主应用程序中有一个加载插件的地方。这里的插件是dll,所以我通过反射去加载这些dll。

public void LoadPlugin() { foreach (string fileName in Directory.GetFiles(Directory.GetCurrentDirectory() + "\\" + "Plugins", "*.dll")) { Assembly assembly = Assembly.LoadFile(fileName); foreach (Type pluginType in assembly.GetTypes()) { if (!pluginType.IsPublic || pluginType.IsAbstract || pluginType.IsInterface) continue; Type concreteType = pluginType.GetInterface(typeof(IPlugin).FullName, true); if (concreteType != null) { IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType); plugin.Initialize(this); pluginList.Add(plugin); break; } } } }

    主应用程序执行的代码如下:

void Start() { //邮件发送祝福 MailNotice("中秋快乐"); //加载插件 LoadPlugin(); //运行插件 if (pluginList.Count > 0) { foreach (IPlugin plugin in pluginList) { plugin.DoSomething(); } } Console.ReadLine(); }

    运行结果如下:

    开发两个插件,都继承IPlugin。

    手机短信通知插件:

public class PluginA : IPlugin { public void Initialize(IPluginHost pluginHost) { IPluginHost myApplication = (IPluginHost)pluginHost; myApplication.AddMenuItem("Click me", OnClick); } private void OnClick(string name) { Console.WriteLine("Omg! You clicked me!"); } public void DoSomething() { Console.WriteLine("手机短信通知:中秋快乐"); } }

 

    MSN通知插件:

public class PluginB : IPlugin { public void Initialize(IPluginHost pluginHost) { IPluginHost myApplication = (IPluginHost)pluginHost; myApplication.AddMenuItem("Click me", OnClick); } private void OnClick(string name) { Console.WriteLine("Omg! You clicked me!"); } public void DoSomething() { Console.WriteLine("MSN信息通知:中秋快乐"); } }

 

    插件的目录如下图:

    运行效果:

 

扩展性和兼容性:

    如果我想在主应用程序中添加一个ShowMessageBox方法。而且这个方法供插件调用。考虑到版本的兼容性,公开的接口是不能修改的。比如:将主应用程序的接口修改成:

public interface IPluginHost { void AddMenuItem(string name, MenuItemClickedHandler clickHandler); void RegisterComponent(T component) where T : class; T GetComponent() where T : class; void MailNotice(string messaage); void ShowMessageBox(string message); }

    那么如何实现呢,很简单,使用依赖注入的方式。添加下面接口:

public interface IMessageBoxHost { void ShowMessageBox(string message); }  

 

    通过主应用程序的构造函数,将MessageBoxHost对下岗注入到主应用程序,在通过插件的构造函数,将其注入插件之中。

主应用程序的构造函数:

public Program(IMessageBoxHost messageBoxHostInstance) { this.messageBoxHostInstance = messageBoxHostInstance; }

 

    插件构造函数:

public PluginA(IMessageBoxHost messageBoxHost) { this.messageBoxHost = messageBoxHost; }

 

    修改实例化插件的代码:

IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType, new object[] { messageBoxHostInstance });

    这样我们对版本兼容有了保障。

总结:本文闲谈了可插拔应用程序的开发原理,文章的后面提供了插件和应用程序之间版本兼容的一种方案。有讨论才有进步,欢迎各位留言。

参考代码:http://files.cnblogs.com/zhuqil/Plugin.rar

参考:

A Flexible Plugin System

A more extensible way to build plugin system

(全文完)

以下为广告部分

您部署的HTTPS网站安全吗?

如果您想看下您的网站HTTPS部署的是否安全,花1分钟时间来 myssl.com 检测以下吧。让您的HTTPS网站变得更安全!

SSL检测评估

快速了解HTTPS网站安全情况。

安全评级(A+、A、A-...)、行业合规检测、证书信息查看、证书链信息以及补完、服务器套件信息、证书兼容性检测等。

SSL证书工具

安装部署SSL证书变得更方便。

SSL证书内容查看、SSL证书格式转换、CSR在线生成、SSL私钥加解密、CAA检测等。

SSL漏洞检测

让服务器远离SSL证书漏洞侵扰

TLS ROBOT漏洞检测、心血漏洞检测、FREAK Attack漏洞检测、SSL Poodle漏洞检测、CCS注入漏洞检测。

标签组:[ssl] [string

本文来源:https://www.kandian5.com/articles/22772.html

相关阅读

唐代《杂诗》原文译文赏析

杂诗唐代:佚名近寒食雨草萋萋,著麦苗风柳映堤。等是有家归未得,杜鹃休向耳边啼。译文时令将近寒食,春雨绵绵春草萋萋;春风过处苗麦摇摆,堤上杨柳依依。这是为什么呵,我却有家归去不得?杜鹃呵,不要在我耳边不...

2025-04-21

《陇西行四首·其二》赏析

陇西行四首·其二唐代:陈陶誓扫匈奴不顾身,五千貂锦丧胡尘。可怜无定河边骨,犹是春闺梦里人!译文唐军将士誓死横扫匈奴奋不顾身,五千身穿锦袍的精兵战死在胡尘。真可怜呵那无定河边成堆的白骨,还是少妇们春闺里...

2025-04-21

《枫桥夜泊》赏析

枫桥夜泊唐代:张继月落乌啼霜满天,江枫渔火对愁眠。姑苏城外寒山寺,夜半钟声到客船。译文月亮已落下乌鸦啼叫寒气满天,江边枫树与船上渔火,难抵我独自傍愁而眠。姑苏城外那寂寞清静寒山古寺,半夜里敲响的钟声传...

2025-04-21

元宵灯联的由来

元宵张灯是我国人民的传统习俗。古往今来,不仅有大量脍炙人口的元宵咏灯诗,而且也留下了无数情趣盎然的元宵吟灯联。元初南宋末,南宋有个叫贾似道的人镇守淮阴(今扬州)时,有一年上元灯节张灯,门客中有人摘唐诗...

2025-04-21

张祜《集灵台·其二》评析

集灵台·其二唐代:张祜虢国夫人承主恩,平明骑马入宫门。却嫌脂粉污颜色,淡扫蛾眉朝至尊。译文虢国夫人受到皇上的宠恩,大清早就骑马进入了宫门。只嫌脂粉会玷污她的美艳,淡描蛾眉就进去朝见至尊。评析这首讽刺虢...

2025-04-21

元宵节的爱情元素

充满诗情和浪漫色彩的元宵节,往往与爱情连在一起。历代诗词中,就有不少诗篇借元宵抒发爱慕之情。北宋欧阳修词“今年元夜时,月与灯依旧;不见去年人,泪满春衫袖。”抒写了对情人的思念之苦。辛弃疾(青玉案)写道...

2025-04-21

唐代《赠内人》诗歌赏析

赠内人唐代:张祜禁门宫树月痕过,媚眼惟看宿鹭窠。斜拔玉钗灯影畔,剔开红焰救飞蛾。译文月光由宫门移到宫树梢,媚眼只看那宿鹭的窝巢。在灯影旁拔下头上玉钗,挑开灯焰救出扑火飞蛾。鉴赏唐代选入宫中宜春院的歌舞...

2025-04-21

张旭《桃花溪》赏析

桃花溪唐代:张旭隐隐飞桥隔野烟,石矶西畔问渔船。桃花尽日随流水,洞在清溪何处边。译文山谷云烟缭绕,溪上飞架的高桥若隐若现;站在岩石西侧询问那捕鱼归来渔人。这里桃花随着流水,终日地漂流不尽,这不就是桃花...

2025-04-21

张泌《寄人》诗歌赏析

寄人唐代:张泌别梦依依到谢家,小廊回合曲阑斜。多情只有春庭月,犹为离人照落花。译文别后思念深深,经常梦到你家。院中风景依旧,小廊曲阑仍在。只有天上春月最是多情,还为离人照着庭院落花。赏析以诗代柬,来表...

2025-04-21

韦应物《滁州西涧》赏析

滁州西涧唐代:韦应物独怜幽草涧边生,上有黄鹂深树鸣。春潮带雨晚来急,野渡无人舟自横。译文最是喜爱涧边生长的幽幽野草,还有那树丛深处婉转啼唱的黄鹂。春潮夹带着暮雨流的湍急,荒野渡口无人,只有一只小船悠闲...

2025-04-21