说不尽的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平台上应用程序的开发市场, 但是最 ...
随机推荐
- Linux 文件锁
当多个进程同时访问操作同一个文件时,我们怎么保证文件数据的正确性. linux通常采用的方法是文件上锁,来避免共享资源的产生竞争状态. 文件锁包括建议性锁和强制性的锁: 建议性的锁 :顾名思义,相对温 ...
- Java值传递和引用传递详细解说
前天在做系统的时候被Java中参数传递问题卡了一下,回头查阅了相关的资料,对参数传递问题有了新的了解和掌握,但是有个问题感觉还是很模糊,就是 Java中到底是否只存在值传递,因为在查阅资料时,经常看到 ...
- mysqldb模块的简单用法
# - *- coding:utf-8-*-import urllib2import reimport MySQLdbimport sysreload(sys)sys.setdefaultencodi ...
- Python_sklearn机器学习库学习笔记(一)_Feature Extraction and Preprocessing(特征提取与预处理)
# Extracting features from categorical variables #Extracting features from categorical variables 独热编 ...
- rhel7系统破root开机密码
破密码: 开机菜单栏第一栏按e,在linux16行尾,加入rd.break console=tty0 ctrl +x继续启动 mount -o remount,rw /sysroot #重新挂载sys ...
- 第三十八章 springboot+docker(maven)
回顾上一章的整个部署过程: 使用"mvn install"进行打包jar 将jar移动到与Dockerfile文件相同的文件夹下 编写Dockerfile文件 使用"do ...
- 如果页面引用了外部JS代码,会被IE缓存的解决方法
在使用jquery时特别常见,明明修改的js,但是经常不生效,因为缓存,解决办法就是清除ie缓存,每次去点ie选项,太麻烦,网上有人用批处理去,还是每次去点,在页面中加入下面几行,就可以禁用缓存 &l ...
- php 解析 视频 信息 封面 标题 图片 支持 优酷, 土豆 酷6 56 新浪 qq播客 乐视 乐视
原文地址:http://www.lianyue.org/2013/2497/ <?php /** * 解析 视频信息 类 * * 支持 优酷, 土豆 酷6 56 新浪 qq播客 乐视 乐视 ** ...
- expdp报错ora 39126
11.2.0.2,expdp报错: ORA-39126: Worker unexpected fatal error in KUPW$WORKER.GET_TABLE_DATA_OBJECTS []O ...
- JDBC常用接口详解
JDBC中常用接口详解 ***DriverManager 第一.注册驱动 第一种方式:DriverManager.registerDriver(new com.mysql.jdbc.Driver()) ...