今日看点

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

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

爱因斯坦和玛加丽塔什么关系

苏联能在如此短的时间内造出原子弹,全靠一个女人,玛加丽塔·科涅库娃,她凭借着自己的美丽的外表和出色的外交手段,俘获的爱因斯坦的芳心,从而窃取了美国研制原子弹和发展高能物理的绝密情报。玛加丽塔本来是一个...

2025-11-03

考拉为什么吃妈妈的屎

考拉,正式名称是树袋熊,澳大利亚的国宝。考拉是澳大利亚奇特的珍贵原始树栖动物,以桉树叶为食,每天能吃掉许多的桉树叶,而且消化良好。但是有说法是考拉是吃屎长大的,这是怎么回事呢?树袋熊大部分的时间都是在...

2025-11-03

紫砂壶有什么好处

紫砂壶之所以受到茶人喜爱,一方面是造型美观,另一方面泡茶时有许多优点。(一)紫砂是一种双重气孔结构的多孔性材质气孔微细,密度高。用紫砂壶沏茶,不失原味。(二)紫砂壶透气性能好使用其泡茶不易变味,暑天越...

2025-11-03

蔡襄究竟在哪修复古五塘的

蔡襄是北宋时期的名臣,多在福建沿海一带做官,造福百姓。蔡襄有一项功绩就是“修复古五塘”,可是这“修建古五塘”的地点究竟是哪里呢,是福建还是莆田?据方志记载,蔡襄于宋庆历五年(1045年)4月至庆历七年...

2025-11-03

古代太子洗马是啥官

官制由来已久,自国家形成后并会逐渐构成一套职官制度,秦汉“三公九卿”、隋唐“三省六部制”等都是官制。几千年的封建王朝,数以千计的官名,那“太子洗马”是什么官?真只是马夫吗?可能和你理解的不一样。这个洗...

2025-11-03

维多利亚女王在位期间英国完成了资本主义工业革命

在维多利亚女王在位期间,英国完成了资本主义工业革命,为了满足国家寻找原料地和销售市场的要求,英国开始在世界各地建立殖民地和自治领。英国工业革命始于18世纪60年代,以棉纺织业的技术革新为始,以瓦特蒸汽...

2025-11-03

古代妃嫔的等级划分

除了乱世个别国家后宫比较混乱意外,历朝历代一般都制定有严格的后宫嫔妃等级,而嫔妃的等级也与其身份地位、福利待遇等息息相关,甚至一度关系到皇位的继承顺位,不过历朝历代的嫔妃等级都有一定程度的差异。以下简...

2025-11-03

袁绍当初如果杀了刘备 关羽会不会留在曹营

今天历史网小编给大家准备了:刘备和关羽,感兴趣的小伙伴们快来看看吧!第一种:关羽会主动留在曹营。如果袁绍真的把刘备给杀了,关羽的第一个反应也是他首要应该做的是如何给刘备报仇。要报仇凭他一已之力当然不行...

2025-11-03

《无忧之夜2025》晚会昨晚于三亚开幕:从小屏到大屏的全新跨越

昨晚,由黄金珠宝上市公司周大生独家冠名,湖南卫视、芒果TV、无忧传媒联合打造的《无忧之夜2025》盛典晚会于三亚市体育中心白鹭体育馆盛大开幕。这场年度盛事成功把无忧传媒的人气与活力,带到了万人瞩目的大...

2025-11-03