说不尽的MVVM(5) - 消息满天飞
知识预备
阅读本文,我假定你具备以下知识:
- C#和WPF基础知识
- Lambda表达式
清楚ViewModel的职责
如果我们的程序需要弹出一个MessageBox,我们应该怎么做?
我见过不少人在ViewModel里面写着:MessageBox.Show("xxx");
程序的功能看似没有什么问题,日后我要把这个ViewModel用到WinRT上,你是不是傻眼了?WinRT是没有MessageBox的。
为什么会出现这样的情况呢?请仔细想想,弹出MessageBox是ViewModel的职责吗?
很明显,MessageBox是与交互相关的东西,对MessageBox的操作应该在UI上执行,我们又知道,ViewModel是不知道View的存在的,那当业务逻辑产生了交互请求时,应该怎样通知UI呢?这里就引出我们今天要讲的Messenger。
通过消息实现松散耦合
这个名词有点抽象,举个简单的例子,老师上课时算一道题,要做一个计算,对同学们说:"哪个同学有计算器的帮我算一下这个。",然后很快有同学算好并且在下面喊:"老师,算好了,这个等于xxx!!!"。
在这里不难看出,老师并不依赖于任何一个学生,他只是简单的发出一个消息,然后同学收到老师的请求,执行操作,并将结果一消息的形式返回给老师。老师只是找了个人帮忙计算,并不需要知道是谁在帮忙计算。
这样的好处应该在如今的云计算时代体现的比较明显,举个例子,我们可以把Web前段和BLL分开,中间通过Windows Azure的Service Bus,以消息的形式进行通信,这样,我们可以根据负载情况,把Web层和BLL分别缩放,而不需要考虑他们的依赖关系。
实现一个简单的Messenger
实现Messenger的思想是:通过一个中心的Dictionary存储消息的标记和处理者的关系,在消息发出时,调用对应的处理者。
这是一个非常简陋的Messenger,我们假定一切正常,没有进行错误处理,对于理解Messenger的思想来说,已经足够了,但在实际应用中,一定要注意。
使用MVVM Light的Messenger
相信通过上一个例子,大家已经对Messenger的机制有了一定的理解,我们现在就来用Messenger实现ViewMoel和View的交互请求。
程序非常简单,点击按钮,弹出消息框。
我们现在Windows里面注册这个消息
然后在ViewModel里面发送消息,这里的"MSG"就是消息的标记,他由消息的发送者和接受者约定,这样,对于这个交互请求,不同的表现层技术可以采用不同的相应方式,例如WPF可以用MessageBox,WinRT可以用MessageDialog。
在这里我们使用Messenger默认提供的实例,当然我们也可以另外创建实例。
你可能会有的疑问
所有的消息集中在一个Messenger,会不会混乱?
从消息的容器里面看,的确凌乱不堪,这也是我把文章题目叫做消息满天飞的原因,但我们最终的目的达到了。想想依赖注入的容器吧,一样的。
Windows Azure Service Bus 是什么东西?
这是Windows Azure提供的一系列系统整合服务,包括队列服务,主题/订阅服务,中继服务,通知中心等,详见:https://www.windowsazure.com/en-us/documentation/services/service-bus/
说不尽的MVVM(5) - 消息满天飞的更多相关文章
- 说不尽的MVVM(1) – Why MVVM
最近学的一篇课文<说不尽的狗>竟让我有了写<说不尽的MVVM>这一想法,事非亵渎,实出无奈.我在刚学WPF不久时听说有MVVM这种东西,做了下尝试,发现他能给程序的设计带来很大 ...
- 说不尽的MVVM(4) – 发号施令的Command
知识预备 阅读本文,我假定你具备以下知识: C# WPF基础知识 知道WPF的命令 WPF相对WinForm加了一种Command的机制,对用户的操作进行更加灵活的处理,相信很多朋友知道并用过Rout ...
- 说不尽的MVVM(3) – 从通知属性说起
上篇我们体验了一个从事件处理程序到MVVM程序的转变,在最后也留下了一个问题:RaisePropertyChanged的原理是什么?今天我们来一探究竟. 通过上节做的小例子我们知道,仅仅修改ViewM ...
- 说不尽的MVVM(2) – MVVM初体验
知识预备 阅读本文,我假定你已经具备以下知识: C#.WPF基础知识 了解Lambda表达式和TPL 对事件驱动模型的了解 知道ICommand接口 发生了什么 某程序员接到一个需求,编写一个媒体渲染 ...
- wpf mvvm模式下 在ViewModel关闭view
本文只是博主用来记录笔记,误喷 使用到到了MVVM中消息通知功能 第一步:在需要关闭窗体中注册消息 public UserView() { this.DataContext = new UserVie ...
- Netty系列之Netty百万级推送服务设计要点
1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...
- Netty_Netty系列之Netty百万级推送服务设计要点
1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...
- 【netty】Netty系列之Netty百万级推送服务设计要点
1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...
- QT 4.2.2的安装(安装完还要再编译,注意设置Windows Path)
(安装篇)前奏: 提到C++的GUI Framework估计大多数人都会想到MFC.VCL,因为在十年前的COM时代,这两个大家伙几乎垄断了整个C++ windows平台上应用程序的开发市场, 但是最 ...
随机推荐
- phpstorm
9XVKERIY9F-eyJsaWNlbnNlSWQiOiI5WFZLRVJJWTlGIiwibGljZW5zZWVOYW1lIjoiYXNoZXIgY2hlbiIsImFzc2lnbmVlTmFtZ ...
- urllib.request
[urllib.request] 1.urlopen结果保存在内存. 2.ulrretrieve结果保存到文件. 3.response有read方法. 4.可以创建Request对象. 5.发送Pos ...
- Ubuntu 针对 SSD 的优化方案
. . . . . 首先看下 LZ 的分区情况: >$ sudo fdisk -l Disk /dev/sda: bytes heads, sectors/track, cylinders, t ...
- php设计模式学习之观察者模式
什么都不说,先看代码: interface userOperateImpl { public function operate($username); } class userLoginLog imp ...
- jquery 滚动到底部加载
var body_ = $(window); var indexPage = 2; var pageCount = <?php echo $pageCount;?>; var _ajaxR ...
- POSIX信号处理
信号用于通知进程发生了某件事情,可以由一个进程发给另一个进程,也可以由内核发个一个进程. 每个信号都有一个关联的行为,可以通过sigaction函数来设置一个信号的行为,有3种选择: 1.定义一个信号 ...
- mysql查询数据返回touple改为字典的方法
conn = MySQLdb.connect(host='ip',user='root',passwd='123456',db="dbname",charset="utf ...
- 使用Dapper时,如何将MySqlParameters[] 变成Dapper.DynamicParameters动态对象
在开发过程中,如何替原生的参数化MySqlParameters[]换成Dpapper的参数化DynamicParameters对象正确的做法:var args = new DynamicParamet ...
- 9x25 串口映射
duart /dev/ttyS0 /dev/ttyS0 usart1 /dev/ttyS2 /dev/ttyS1 usart2 /dev/ttyS3 ...
- SQL2008性能计数器注册表配置单元一致性失败
按照这个操作 http://jingyan.baidu.com/article/7c6fb4287c923880652c9074.html如果在注册表中没有 HKEY_LOCAL_MACHINE\SO ...