Prism 源码解读6-事件聚合
0 介绍
事件提供的是1对多的绑定,通过委托链实现对订阅者的调用,事件必须要通过发布者调用。同时事件订阅是强引用,事件订阅者的生命周期总是大于等于事件发布者。如果代码中事件很多就会充斥着各种事件的订阅,不利于维护。
Prism提供了EventAggregator器,可以在任何地方进行订阅,任何地方进行调用/发布,实例只对EventAggregator和事件类型有依赖,使用了弱引用,可以过滤消息,并可以控制回调函数线程。感觉很强大,实现应该挺复杂,但看到实现时有一种恍然大悟的感觉,喜欢这种简单而强大的实现。开始一探究竟吧!
1 整体框架
先从整体框架解析一下吧。EventAggregator

发现这只是一个集合类,保存着事件类型和事件实例,还有一个线程上下文保证线程同步。

看一下EventBase,看来所有的订阅委托都是在着保存着,因为有一个IEventSubscription列表。EventSubscription因该是订阅委托的包装器。

看到有SubscriptionToken和DelegateReference,

这边终于看到Delegate的真正存放地点了。这边存放了弱引用,委托类型和MethodInfo。
看到这边理解了,通过一个集合保存事件,这个事件内部存储着所有订阅委托。
当我们向订阅发布的时候,只要从这个集合中获取对应的事件进行订阅发布。相通了是不是觉得自己也能写一个简单的事件聚合器呢?
2 具体代码
来具体看看代码吧。

看到EventAggregator通过依赖注入,获取MessageSentEvent进行订阅。

保存了UI线程上下文和将事件类型和事件类型实例放到集合中,加锁,线程安全。

事件可以啥都没有但必须继承PubSubEvent,功能都在这里实现了。

threadOption默认是PublisherTHread,这里是说回调函数在什么线程执行,BackgroundThread就是Task创建的线程池线程,Dispatcher就是UI线程



内部订阅进行了校验(主要是委托不为空)和Token

看完订阅再来看看调用

在任何地方调用,还是去EventAggregator获取事件实例,然后调用其Publish


从这边可以看出就是依次调用列表中的委托,DispatcherEventSubscription 调用

BackgroundEventSubscription 调用

到现在还没有讲到Filter,来看看怎么实现过滤消息

在订阅的时候值接受含有Brian的消息
使用了泛型的订阅


使用了prcidate<>保存了filter委托,
在Publish主要就是在GetExecutionStrategy方法中

filter返回true触发订阅委托。
总结
事件聚合提供了一个很好的思路,我们甚至可以利用事件聚合的思想实现事件聚合微服务组件。
Prism 源码解读6-事件聚合的更多相关文章
- Prism 源码解读1-Bootstrapper和Region的创建
		
介绍 之前也研究过Prism框架但是一直没有深入理解,现在项目上想把一个Winform的桌面应用程序改造成WPF程序,同时我希望程序是可测试可维护架构良好的,Prism的这些设计理念正好符合我的需求, ...
 - Prism 源码解读5-数据绑定和命令
		
介绍 WPF本身就支持通知.绑定和命令,实现ViewModel和VIew之间的通讯,但相对来说功能比较少,Prism扩充了这些功能并提供更加强有力,简洁的数据绑定和命令. 0 绑定通知 WPF的绑定通 ...
 - Prism 源码解读2-View的加载和控制
		
介绍 上一篇介绍了Region,这一篇跟Region息息相关,讲一下Region中View的加载方式及控制. 4.ViewDiscovery 在创建好Region后需要将View添加到Region中. ...
 - Prism 源码解读3-Modules加载
		
介绍 在软件开发过程中,总想组件式的开发方式,各个组件之间最好互不影响,独立测试.Prism的Modules很好的满足了这一点. 这个架构图很好了讲解了Prism的Modules的概念 Prism支持 ...
 - Prism 源码解读7-导航
		
介绍 Prism提供了一个非常强大的功能导航,导航的意思就是指定对应的View显示.这个导航的强大之处有: 可以设置导航前后的动作 可以指定View实例的生命周期,可以是否导航到新的View实例 提供 ...
 - Prism 源码解读4-ViewModel注入
		
介绍 介绍一个Prism的MVVM实现,主要介绍Prism如何在WPF上进行的一些封装,以实现MVVM.MVVM到底是什么呢?看一下这一幅经典的图 以前没有ViewModel这个概念,就是将Model ...
 - AFNetworking 3.0 源码解读 总结(干货)(下)
		
承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...
 - AFNetworking 3.0 源码解读 总结(干货)(上)
		
养成记笔记的习惯,对于一个软件工程师来说,我觉得很重要.记得在知乎上看到过一个问题,说是人类最大的缺点是什么?我个人觉得记忆算是一个缺点.它就像时间一样,会自己消散. 前言 终于写完了 AFNetwo ...
 - AFNetworking 3.0 源码解读(十)之 UIActivityIndicatorView/UIRefreshControl/UIImageView + AFNetworking
		
我们应该看到过很多类似这样的例子:某个控件拥有加载网络图片的能力.但这究竟是怎么做到的呢?看完这篇文章就明白了. 前言 这篇我们会介绍 AFNetworking 中的3个UIKit中的分类.UIAct ...
 
随机推荐
- js中如何判断属性是对象实例中的属性还是原型中的属性
			
ECMAScript5中的hasOwnProperty()方法,用于判断只在属性存在与对象实例中的时候,返回true,in操作符只要通过对象能访问到属性就返回true. 因此只要in操作符返回true ...
 - 使用webpack从0搭建多入口网站脚手架,可复用导航栏/底部通栏/侧边栏,根据页面文件自动更改配置,支持ES6/Less
			
之前只知道webpack很强大,但是一直没有深入学习过,这次从头看了一下教程,然后从0开始搭建了一个多入口网站的开发脚手架,期间遇到过很多问题,所以有心整理一下,希望能给大家一点帮助. 多HTML网站 ...
 - 通过HTML及CSS模拟报纸排版总结
			
任务目的 深入掌握CSS中的字体.背景.颜色等属性的设置 进一步练习CSS布局 任务描述 参考 PDS设计稿(点击下载),实现页面开发,要求实现效果与 样例(点击查看) 基本一致 页面中的各字体大小, ...
 - Pycharm IDE安装及注册激活笔记(1)
			
一.Windows 下的安装及激活. 1.首先去Pycharm官网,或者直接输入网址:http://www.jetbrains.com/pycharm/download/#section=window ...
 - CSS3新单位vw,vh,vmin,vmax详解
			
1,vw,vh,vmin,vmax是由视窗Viewport大小来决定的,单位1,代表1%,是一种相对单位,只要是为响应式适配视窗的一种解决方案: vw:view width(视窗宽度)的百分比,1vw ...
 - 自定义FrameWork
			
本项目是基于iOS-Universal-Framework-master框架制作的,故编译之前需要安装iOS-Universal-Framework-master框架, 步骤如下:1.跳转到iOS-U ...
 - 如何为SpringBoot服务添加HTTPS证书
			
HTTPS是HTTP的安全版本,旨在提供数据传输层安全性(TLS).当你的应用不使用HTTP协议的时候,浏览器地址栏就会出现一个不安全的提示.HTTPS加密每个数据包以安全方式进行传输,并保护敏感数据 ...
 - Redis系列五 - 哨兵、持久化、主从
			
问:骚年,都说Redis很快,那你知道这是为什么吗? 答:英俊潇洒的面试官,您好.我们可以先看一下 关系型数据库 和 Redis 本质上的区别. Redis采用的是基于内存的,采用的是单进程单线程模型 ...
 - 如何使用Logstash
			
目录 一.什么是Logstash 二.如何安装 三.快速使用 四.Input输入插件 五.codec编码插件 六.filter过滤器插件 七.output输出插件 八.总结 一.什么是Logstash ...
 - this.baseInfoList = [...this.baseInfoList] 所有和数组有关的操作,最后一定都展开一次,否则就没有双向绑定!!
			
this.baseInfoList = [...this.baseInfoList] 所有和数组有关的操作,最后一定都展开一次,否则就没有双向绑定!! this.baseInfoList = [... ...