咨询热线:18874553252 联系人:罗经理 地址:北京市丰台区郑王坟南6号6层654号
MEF 插件式开发 - 小试牛刀
来源:金世豪官方注册页面 发布时间:2019-10-29 点击量:460
目录
MEF 简介实践出真知面向接口编程控制反转(IOC)构建入门级 MEF相关参考MEF 简介
Managed Extensibility Framework 即 MEF 是用于创建轻量、可扩展应用程序的库。 它让应用程序开发人员得以发现和使用扩展且无需配置。 它还让扩展开发人员得以轻松地封装代码并避免脆弱的紧密依赖性。 MEF 让扩展不仅可在应用程序内重复使用,还可以跨程序重复使用。
在进行传统的 C/S 端开发,如果项目不是特别复杂,常规的开发模式还是可以应对的。但是一旦场景复杂度提升,一个小小业务功能的修改就需要更新整个客户端,这个对于开发者来说是不能忍受的。因此微软为我们引入了 MEF 的开发模式。允许我们将众多的业务模块拆分开来设计成独立的 DLL,然后由客户端来进行统一加载,这样就能解决上述我们所说的痛点。
实践出真知
创建一个高扩张的 MEF 框架涉及的技术点较多。为了方便初学者能较快理解,上手实践,我这里主要通过 3 个方面来进行相关叙述。
面向接口编程
如果你还不能理解什么是面向接口编程的话,那你应该还不能区分抽象类和接口之间的区别。其实在刚开始的时候我也不是很能理解,直到我看到了一句话:抽象类规定了你是什么,接口规定了你能干什么,只要你能理解这句话,那么你应该就明白什么是面向接口编程,这种编程方式的好处是统一化了业务的暴露方式,方便外部使用。下面我们看一个简单的例子。
public interface IMessage{ void Send();}public class EmailService : IMessage{ public void Send() { Console.WriteLine("Email Send Message"); }}public class SMSService : IMessage{ public void Send() { Console.WriteLine("SMS Send Message"); }}class Program{ static void Main(string[] args) { IMessage email = new EmailService(); email.Send(); IMessage sms = new SMSService(); sms.Send(); Console.ReadKey(); }}
上述代码中,我们创建了一个 IPlugin 的接口,接口定义了一个 ShowPluginName() 方法,然后我们再定义了两个独立的类来分别继承该接口并实现相应的接口函数。在主函数中,我们只需要定义一个接口类型的对象,然后接收一个具体的类型实例,函数就会输出对应的正确信息。这样编程的好处就不言而喻了。代码很简单,这里就不过多描述。输出结果如下图所示
控制反转(IOC)
所谓控制反转,就是将对象初始化的控制权交出去。要实现控制反转,我们需要有面向接口编程的接口,同样的,这里也是展示一个代码段来叙述。
public interface IMessage{ void Send();}public class EmailService : IMessage{ public void Send() { Console.WriteLine("Email Send Message"); }}public class SMSService : IMessage{ public void Send() { Console.WriteLine("SMS Send Message"); }}public static class Factory{ public static EmailService GetEmailService() => new EmailService(); public static SMSService GetSMSService() => new SMSService();}class Program{ static void Main(string[] args) { Console.WriteLine("DependencyService:"); DependencyService(); Console.WriteLine(); Console.WriteLine("InversionDependencyService:"); InversionDependencyService(); Console.ReadKey(); } static void DependencyService() { EmailService fooEmailService = new EmailService(); fooEmailService.Send(); } static void InversionDependencyService() { IMessage fooMessage = Factory.GetEmailService(); fooMessage.Send(); fooMessage = Factory.GetSMSService(); fooMessage.Send(); }}
在这个例子中,我们通过工厂模式创建具体的服务,然后供主程序来调用,代码依然很简单,分别用传统创建服务的方式和 控制反转的方式来进行对比。程序输出如下
构建入门级 MEF
有了上面两个知识点做铺垫,我们可以开始创建一个入门级的 MEF 示例程序。想要在程序中使用 MEF 的话需要引入如下程序集
System.ComponentModel.Composition这里还是以控制台程序来展示。项目结构如下图所示
注意:上述所有项目程序的输出目录需要保持一致
MefSample.Core 代码段
public interface IMessage{ void Send();}
MefSample.EmailService 代码段
[Export(typeof(IMessage))]public class EmailService: IMessage{ public void Send() { Console.WriteLine("Email Send Message"); }}
MefSample.SMSService 代码段
[Export(typeof(IMessage))]public class SMSService : IMessage{ public void Send() { Console.WriteLine("SMS Send Message"); }}
MefSample 代码段
class Program{ static void Main(string[] args) { var dir = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory); var catalog = new DirectoryCatalog(dir.FullName, "*.dll"); using (CompositionContainer container = new CompositionContainer(catalog)) { IEnumerable<IMessage> messages = container.GetExportedValues<IMessage>(); if (messages != null) { foreach (var message in messages) { message.Send(); } } } Console.ReadKey(); }}
仔细观察的话,其实上述代码还是挺简单的, 我这里使用了 DirectoryCatalog 的方式来寻找目标插件,感兴趣的朋友可以试试其他方式:AggregateCatalog
、AssemblyCatalog
、DirectoryCatalog
。当然,你也可以自定义。程序输出结果如下图所示
好了,程序写到这里相信你对 MEF 也多少有些了解。我没有过多的讲解抽象理论,而是更多地通过代码来描述我所想要说的。在下篇文章中,我将会简单讲述一下 MEF 在 WPF 中的入门使用,方便初学者更上一层楼。加油,共勉!
相关参考
Managed Extensibility Framework (MEF)CSharpDICSharpDI.Notes, 1, 0, 9);相关产品
-
凉水河的治理过程,其实是北京水污染治理的缩影。尽管多年来水务部门采取多种治理措施,但是由于流域人口增长过快,污水处理设施跟不上,治污效果出现反复。值得肯定的是,北京市自2013年打响治污攻坚战,力度不断加码,对市民反映强烈的黑臭水体采取标本兼治措施,凉水河在未来不久可以解决其恶臭问题。
-
43岁的马克-威廉姆斯再次焕发了青春的活力,他已经成为本届斯诺克世锦赛,战至此时还留在这里的、最年长的球员。在1/4决赛第一阶段结束后,“金左手”发毒誓:如果赢得世锦赛冠军,就在克鲁斯堡“裸奔”!
-
据知名博主长春国贸爆料,在《这就是生活》录制漂流期间,王琳因不满太过虐星的设置弄得如此狼狈,加上身体不适,与节目组发生摩擦,提出中止录制,一上岸便怒斥摄制组太过分,遂提出中止录制,最后甚至在没有完成全部录制内容的情况下与经纪人一起愤然离开,没有完成最后的录制。
-
动力方面,国产捷豹XEL将会搭载全新的2.0T Ingenium发动机,分为高低两种调校,最大功率分别为200马力和250马力,峰值扭矩分别为320牛·米和365牛·米。传动方面则匹配8速自动变速箱。而新增的进口XE R-SPORT则使用一台最大功率达300马力的2.0T发动机,进一步丰富消费者的选择。(文/图 汽车之家 陈海佣)
-
中国人民银行近些年频频对外表示,在支付领域将积极拥抱开放政策,既鼓励中国支付公司走出去,也将欢迎国际公司进入中国市场。“我国将大幅放宽金融业市场准入,欢迎和鼓励外资进入支付清算市场。我国将全面开放支付产业的交易、清算和结算环节,全面放开账户、支付工具和支付系统业务。”去年11月,央行副行长范一飞的讲话言犹在耳。
-
澳大利亚澳华电视传媒董事长任传功也发现不少“值得向海外华人华侨讲述的好故事”。尤其是儋州市铁匠村村民结合资源优势,因地制宜,通过创新创业,打造品牌,从昔日打铁工匠成为巧手“鲁班”,给任传功留下深刻印象。
-
鲁照宁透露,今年12月13日南京大屠杀死难者国家公祭日之前,他还有一批史料将带回南京捐赠,包括已征集到的、美国发行的2枚日本投降纪念银块等。
-
个性是喜剧之魂,和老搭档沈腾不同,常远不那么外露闹腾,风格轻暖细腻,在《欢乐喜剧人》中还玩了几回直击80后的回忆杀:致敬Beyond乐队的演唱、灌篮高手的校园风,唤起同龄人共鸣。正如他所说,“图安稳就不来这儿表演了”,节目以喜剧为名,常远自己添了些热血、励志、有念想的尾巴,既为自己,也为同龄的人们。
热点资讯
- 利用扩展符排序合并数组,记录下来分享给大家2019-07-09
- 苹果AppleWatch新玩法:可当窃听器2019-07-09
- 为什么广东都下雪了,北京却还在等?2019-07-09
- 小米MIX3滑盖全面屏官宣!10月25日北京发布2019-07-09
- 谷歌开发者公众号:小米/HMD/索尼/OV等手机今年秋季收到安卓9Pie正式版更新2019-07-09
- 一线|马斯克计划购入2000万美元特斯拉股票2019-07-09
- 腾讯数据中心签约重庆电信打造跨时代智能运维解决方案2019-07-09
- 苹果iPhoneXS等新机爆料汇总:这几点需要注意2019-10-29