今日看点

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

发表于话题:闲淡抄人
发布时间: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

相关阅读

《魅影神捕》开机 罗云熙“清冷双面弃子”试炼人性灰度

6月13日,由爱奇艺出品、北京战友文化联合出品及承制、中视同成联合承制、爱奇艺爱撒糖工作室联合打造的古装悬疑探案剧《魅影神捕》在横店举行开机仪式。该剧由龚宇、原昕担任出品人,王晓晖担任总监制,邵文...

2025-06-14

齐桓公称霸天下的多维密码:地理、改革与战略的完美融合

齐桓公(前685年-前643年在位)作为春秋五霸之首,其称霸之路绝非偶然。从地理优势到制度革新,从人才选拔到外交策略,齐桓公的霸业是多重因素交织的结果。 一、地理优势:资源禀赋奠定物质基础 齐国地...

2025-06-14

新加坡演员孙政双线出击!《微笑一号店》展暖男本色《临江仙》塑冷酷龙渊

近期,新加坡演员孙政以截然不同的形象活跃于中国观众的视野,在热播的经营纪实互动真人秀综艺《微笑一号店》中,孙政是笑容温暖、阳光清爽的甜品学员;而在同期上线的仙侠剧《临江仙》里,孙政则化身气场迫人、神情...

2025-06-14

秦武王之后:秦昭襄王的崛起与秦国霸业的转折

秦武王嬴荡在位仅四年,便因“举鼎绝膑”的意外事件殒命,其短暂统治如流星划过秦国崛起的历史长空。然而,这位以“勇力”著称的君主之死,却意外成为秦国政治格局剧变的导火索。他的离世不仅揭开秦国高层权力斗争的...

2025-06-14

SEVENTEEN为日韩合拍剧《初恋DOGs》献唱主题曲《Where love passed》

6月13日,据韩媒消息,组合SEVENTEEN为日韩合拍剧《初恋DOGs》献唱主题曲《Where love passed》,成员WOOZI亲自作词作曲。13日,所属社PLEDIS表示:“...

2025-06-14

秦始皇可能活在地宫吗?历史、科学与传说的三重解构

在骊山北麓的苍茫雾霭中,秦始皇陵地宫如同一部未解的密码,千百年来引发无数猜想。从“以水银为百川江河”的《史记》记载,到现代考古探测到的“强汞异常”,这座地下帝国始终笼罩着神秘色彩。然而,当我们将“秦始...

2025-06-14

防弹少年团田柾国就帽子争议进行道歉 今后将谨慎注意

防弹少年团田柾国因佩戴了印有疑似涉及日本右翼字句的帽子引发争议,随后在Weverse公开致歉。14日凌晨,田柾国在Weverse发文表示:"因在彩排过程中佩戴了一顶印有特定字句的帽子,令许多粉丝感到...

2025-06-14

泰山封禅在哪里举行:揭秘中国古代帝王与泰山的神圣对话

在中国古代帝王的心目中,泰山绝非一座普通的山岳,而是“天人合一”的神圣象征。自秦始皇起,历代帝王封禅泰山的传统延续千年,这一仪式不仅是对泰山地理高度的征服,更是对精神权威的终极宣告。然而,泰山封禅究竟...

2025-06-14

相叶雅纪迎来第二个孩子 2021年与妻子结婚

据日媒报道表示,岚成员相叶雅纪的第二个孩子已经出生,这一消息在《女性Seven》的采访中得到证实,网友们也纷纷祝福相叶雅纪。现在岚5位成员中有3位已经结婚,3位成员都有了孩子。二宫和也有2个孩子,樱...

2025-06-14

嬴驷与秦始皇:跨越百年的帝国奠基之路

在秦国统一天下的历史长卷中,嬴驷(秦惠文王)与嬴政(秦始皇)的名字犹如两座巍峨的丰碑,相隔百年却血脉相连。这位高祖父与玄孙的传承关系,不仅是简单的家族谱系延续,更是秦国从“偏居西陲”到“横扫六合”的战...

2025-06-14