2021-01-08

博客园Logo
首页
新闻
博问
专区
闪存
班级
代码改变世界
搜索
注册
登录
猿来到此
博客园 首页 博问 闪存 新随笔 订阅 订阅 管理
随笔 - 34, 文章 - 14, 评论 - 1
关于.NET中的控制反转(二)- 依赖注入之 MEF
一、MEF是什么

   Managed Extensibility Framework (MEF) 是用于创建可扩展的轻量级应用程序的库。 它让应用程序开发人员得以发现和使用扩展且无需配置。 它还让扩展开发人员得以轻松地封装代码并避免脆弱的紧密依赖性。 MEF 让扩展不仅可在应用程序内重复使用,还可以跨程序重复使用。

  MEF 通过组合提供了一种隐式发现它们的方法,而不是明确记录可用组件。 MEF 组件(称为一个部件),以声明方式详细说明了其依赖项(称为导入)及其可提供的功能(称为导出)。 当创建一个部分时,MEF 组合引擎利用从其他部分获得的功能满足其导入需要。

 一句话,MEF就是面向接口编程的应用,接口定义行为,它把实例化类放到代码运行的时候,通过容器参数确定。

二、MEF示例

   在我们国家,不管你在哪个银行办理银行卡,只要银行卡有银联标识,那么你就基本可以在任意一家银行取钱、存钱。中国银联(China UnionPay)成立于2002年3月,是经国务院同意,中国人民银行批准设立的中国银行卡联合组织,在境内的银行必须都支持银联。也就是说,中国银联定义了一些行为,例如用户可以取钱、存钱,任意一家境内银行都必须支持银联定义的行为。因此,你在任意一家银行办理银行卡后,就可以在所有的银行都进行取钱、存钱等及行为。下面我们以此为例,进行一个简单的例子:

复制代码
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel.Composition;
4 using System.ComponentModel.Composition.Hosting;
5 using System.Linq;
6 using System.Reflection;
7 using System.Text;
8 using System.Threading.Tasks;
9
10 namespace MEF1
11 {
12 class Operation
13 {
14 static void Main(string[] args)
15 {
16 BlankOperation(“CBC”,300,100);
17 Console.WriteLine("------------------------------");
18 BlankOperation(“BOC”,888,666);
19 Console.ReadKey();
20 }
21
22 static void BlankOperation(string bankName,int saveMonenyAmout,int withdrawMoneyAmount)
23 {
24 var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
25 CompositionContainer container = new CompositionContainer(catalog);
26 var dev = container.GetExportedValue(bankName);
27 dev.SaveMoneny(saveMonenyAmout);
28 dev.WithdrawMoney(withdrawMoneyAmount);
29 }
30 }
31
32
33 interface IUnionPay
34 {
35 ///
36 /// 存钱
37 ///
38 /// 存钱金额
39 void SaveMoneny(int amount);
40
41 ///
42 /// 取钱
43 ///
44 /// 取钱金额
45 void WithdrawMoney(int amount);
46
47 }
48
49 ///
50 /// 工商银行
51 ///
52 [Export(“CBC”,typeof(IUnionPay))]
53 class ICBC : IUnionPay
54 {
55 public void SaveMoneny(int amount)
56 {
57 Console.WriteLine(KaTeX parse error: Expected 'EOF', got '}' at position 39: …); 58 }̲ 59 60 …“从工商银行取钱,金额为:{amount}”);
63 }
64 }
65
66 ///
67 /// 建设银行
68 ///
69 [Export(“CCB”, typeof(IUnionPay))]
70 class CCB : IUnionPay
71 {
72 public void SaveMoneny(int amount)
73 {
74 Console.WriteLine(KaTeX parse error: Expected 'EOF', got '}' at position 39: …); 75 }̲ 76 77 …“从建设银行取钱,金额为:{amount}”);
80 }
81 }
82
83 ///
84 /// 农业银行
85 ///
86 [Export(“ABC”, typeof(IUnionPay))]
87 class ABC : IUnionPay
88 {
89 public void SaveMoneny(int amount)
90 {
91 Console.WriteLine(KaTeX parse error: Expected 'EOF', got '}' at position 39: …); 92 }̲ 93 94 …“从建设银行取钱,金额为:{amount}”);
97 }
98 }
99
100 ///
101 /// 中国银行
102 ///
103 [Export(“BOC”, typeof(IUnionPay))]
104 class BOC : IUnionPay
105 {
106 public void SaveMoneny(int amount)
107 {
108 Console.WriteLine(KaTeX parse error: Expected 'EOF', got '}' at position 39: …); 109 }̲ 110 111 …“从建设银行取钱,金额为:{amount}”);
114 }
115 }
116 }
复制代码
代码运行后,效果如下:

三、MEF示例改进

  那如果我们再增加一个银行实现类,例如招商银行,那么需要在MEF1解决方案中增加一个 “CMB”类。但如果我们的程序已经运行了,此时关闭程序,就会影响用户在四大行也无法进行取钱和存钱了,那如何在不关闭程序的前提下,还完成招商银行接入银联卡呢?

 答案是为每个银行实现类创建一个解决方案,然后编译成dll文件,这样我们在支持招商银行接入银联时,只需要把 “CMB.dll”文件放入对应目录,就可以即不关闭主程序,还可以无缝支持招商银行接入银联,方案目录如下:

  

 我们把实现银联的银行的解决方案的生成目录保存在目录 “..\bin\Debug\bank\”,用于测试的解决方案和银联接口的解决方案生成目录保存在目录 “..\bin\Debug\”,编译程序,生成文件如下图:

然后测试解决方案LOC容器加载的目录也需修改为bank目录下:

复制代码
1 using ChinaUnionPay;
2 using System;
3 using System.Collections.Generic;
4 using System.ComponentModel.Composition.Hosting;
5 using System.IO;
6 using System.Linq;
7 using System.Reflection;
8 using System.Text;
9 using System.Threading.Tasks;
10
11 namespace BankOperation
12 {
13 class Program
14 {
15 static void Main(string[] args)
16 {
17 while (true)
18 {
19 Console.Write($“请输入银行名称:”);
20 string name = Console.ReadLine();
21 BlankOperation(name, 300, 100);
22 Console.WriteLine("----------------------------------");
23 }
24 }
25
26 static void BlankOperation(string bankName, int saveMonenyAmout, int withdrawMoneyAmount)
27 {
28 AggregateCatalog catelog = new AggregateCatalog();
29
30 // 添加部件所在文件目录
31 string path = $"{Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath)}\bank\";
32 catelog.Catalogs.Add(new DirectoryCatalog(path));
33
34 // 声明容器
35 CompositionContainer container = new CompositionContainer(catelog);
36 var dev = container.GetExportedValue(bankName);
37
38 // 动作调用
39 dev.SaveMoneny(saveMonenyAmout);
40 dev.WithdrawMoney(withdrawMoneyAmount);
41 }
42 }
43 }
复制代码
此时运行测试程序,运行效果如下:

此时,若在程序运行的时候添加招商银行,我们需添加招商银行的解决方案如下,然后编译生成:

复制代码
1 using ChinaUnionPay;
2 using System;
3 using System.Collections.Generic;
4 using System.ComponentModel.Composition;
5 using System.Linq;
6 using System.Text;
7 using System.Threading.Tasks;
8
9 namespace CMB
10 {
11 ///
12 /// 招商银行
13 ///
14 [Export(“CMB”,typeof(IUnionPay))]
15 public class Operation : IUnionPay
16 {
17 public void SaveMoneny(int amount)
18 {
19 Console.WriteLine(KaTeX parse error: Expected 'EOF', got '}' at position 38: …"); 20 }̲ 21 22 …“从招商银行取钱,金额为:{amount}”);
25 }
26 }
27 }
复制代码
运行效果如下:

我们发现,使用MEF模式可以“高内聚,低耦合”,大大降低了代码的解耦,每次使一个银行接入银行的时候,完全不影响其他银行的正常业务操作。

四、示例代码地址

  代码地址:https://github.com/Dwayne112401/MEFDemo.git

  控制反转(一)地址:https://www.cnblogs.com/dongweian/p/12511272.html

好文要顶 关注我 收藏该文
Dwaynerbing
关注 - 31
粉丝 - 6
+加关注
00
« 上一篇: C# 串口连接的读取与发送(附串口工具的编写源码)
posted on 2021-01-07 22:10 Dwaynerbing 阅读(90) 评论(0) 编辑 收藏
刷新评论刷新页面返回顶部
登录后才能发表评论,立即 登录 或 注册, 访问 网站首页
【推荐】News: 大型组态、工控、仿真、CADGIS 50万行VC++源码免费下载
【推荐】有你助力,更好为你——博客园用户消费观调查,附带小惊喜!
【推荐】AWS携手博客园为开发者送福利,注册立享12个月免费套餐
【推荐】第一个NoSQL数据库,在大规模和一致性之间找到了平衡
【推荐】七牛云新老用户同享 1 分钱抢 CDN 1TB流量大礼包!
【推荐】了不起的开发者,挡不住的华为,园子里的品牌专区
【推荐】未知数的距离,毫秒间的传递,声网与你实时互动

相关博文:
· 超燃|2019中国.NET开发者峰会视频发布
· 刷新.NET
· 通俗易懂,什么是.NET/.NETFramework/.NETCore/.NetStandard?
· WebViewnet::ERR_CLEARTEXT_NOT_PERMITTED&&net::ERR_INTERNET_DISCONNECTED
· DOTNET
» 更多推荐…

最新 IT 新闻:
· 刹不住车了:比特币再创价格新高!破3.7万美元
· 华为P40、Mate 30等多款老机型上线智感支付功能!抬手自动弹出付款码
· 2025年中国大陆芯片将达2230亿美元 但自给率仍不到20%?
· 法拉第未来任命新CFO!贾跃亭激动发声
· 瑞幸咖啡“宫斗大戏”背后:陆正耀还想当王
» 更多新闻…
昵称: Dwaynerbing
园龄: 3年7个月
粉丝: 6
关注: 31
+加关注

< 2021年1月 >
日 一 二 三 四 五 六
27 28 29 30 31 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 1 2 3 4 5 6
搜索

常用链接
我的随笔
我的评论
我的参与
最新评论
我的标签
我的标签
C#(18)
VB.NET(10)
.NET(6)
Access(6)
随笔分类
C#(15)
git(2)
Visual Studio(1)
WPF(3)
编程工具(5)
算法(1)
随笔档案
2021年1月(2)
2020年12月(4)
2020年9月(4)
2020年7月(4)
2020年5月(1)
2020年4月(8)
2020年3月(5)
2018年1月(2)
2017年12月(2)
2017年11月(2)
文章分类
C#(12)
VB.NET(9)
最新评论

  1. Re:C# 使用 log4net 日志组件
    NLog也还行,轻量

–delowly
阅读排行榜

  1. C# Main函数详解(13813)
  2. .NET写入文件操作(2045)
  3. DataGridView显示数据库内容及更新内容到数据库(1587)
  4. git里面分支命名规范(611)
  5. git客户端管理使用工具sourcetree 离线免注册登录安装教程(429)
    评论排行榜
  6. C# 使用 log4net 日志组件(1)
    推荐排行榜
  7. C# 串口连接的读取与发送(附串口工具的编写源码)(2)
    Copyright © 2021 Dwaynerbing
    Powered by .NET 5.0 on Kubernetes Powered By博客园
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值