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-事件聚合的更多相关文章

  1. Prism 源码解读1-Bootstrapper和Region的创建

    介绍 之前也研究过Prism框架但是一直没有深入理解,现在项目上想把一个Winform的桌面应用程序改造成WPF程序,同时我希望程序是可测试可维护架构良好的,Prism的这些设计理念正好符合我的需求, ...

  2. Prism 源码解读5-数据绑定和命令

    介绍 WPF本身就支持通知.绑定和命令,实现ViewModel和VIew之间的通讯,但相对来说功能比较少,Prism扩充了这些功能并提供更加强有力,简洁的数据绑定和命令. 0 绑定通知 WPF的绑定通 ...

  3. Prism 源码解读2-View的加载和控制

    介绍 上一篇介绍了Region,这一篇跟Region息息相关,讲一下Region中View的加载方式及控制. 4.ViewDiscovery 在创建好Region后需要将View添加到Region中. ...

  4. Prism 源码解读3-Modules加载

    介绍 在软件开发过程中,总想组件式的开发方式,各个组件之间最好互不影响,独立测试.Prism的Modules很好的满足了这一点. 这个架构图很好了讲解了Prism的Modules的概念 Prism支持 ...

  5. Prism 源码解读7-导航

    介绍 Prism提供了一个非常强大的功能导航,导航的意思就是指定对应的View显示.这个导航的强大之处有: 可以设置导航前后的动作 可以指定View实例的生命周期,可以是否导航到新的View实例 提供 ...

  6. Prism 源码解读4-ViewModel注入

    介绍 介绍一个Prism的MVVM实现,主要介绍Prism如何在WPF上进行的一些封装,以实现MVVM.MVVM到底是什么呢?看一下这一幅经典的图 以前没有ViewModel这个概念,就是将Model ...

  7. AFNetworking 3.0 源码解读 总结(干货)(下)

    承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...

  8. AFNetworking 3.0 源码解读 总结(干货)(上)

    养成记笔记的习惯,对于一个软件工程师来说,我觉得很重要.记得在知乎上看到过一个问题,说是人类最大的缺点是什么?我个人觉得记忆算是一个缺点.它就像时间一样,会自己消散. 前言 终于写完了 AFNetwo ...

  9. AFNetworking 3.0 源码解读(十)之 UIActivityIndicatorView/UIRefreshControl/UIImageView + AFNetworking

    我们应该看到过很多类似这样的例子:某个控件拥有加载网络图片的能力.但这究竟是怎么做到的呢?看完这篇文章就明白了. 前言 这篇我们会介绍 AFNetworking 中的3个UIKit中的分类.UIAct ...

随机推荐

  1. Ubutun18.04安装Python3.7.6

    最近因为环境问题,简单记录下Python3.7的安装过程: 下载地址:http://python.org/ftp/python/3.7.6/Python-3.7.6.tgz 编译安装步骤: sudo ...

  2. 先导篇:SpringCloud介绍篇

    1.什么是SpringCloud Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线.负载 ...

  3. a标签嵌套href默认行为与子元素click事件存在影响

    2018-08-07 Question about work 开发过程中遇到问题,简单写个demo 运行环境为Chrome 68 描述一下这个问题,当<a>标签内部存在嵌套时, 父元素&l ...

  4. nx-admin1.2版本发布

    nx-admin 是一个开源的管理系统前端集成方案 github地址 nx-admin的初心 组件更易用, 让每个小白快速上手, 最大程度上帮助个人,企业节省时间成本和费用开支. 尽管这个过程不简单, ...

  5. python 深浅拷贝 元组 字典 集合操作

    深浅拷贝 :值拷贝 :ls = [,,] res = ls 则print(res)就是[,,] 浅拷贝 :ls.copy() 深拷贝:ls3 = deepcopy(ls) # 新开辟列表空间,ls列表 ...

  6. Git提交代码冲突:commit your changes or stash them before you can merge.

    用git pull拉取远程分支代码时候遇到如下问题: error: Your local changes to the following files would be overwritten by ...

  7. jQuery插件select2跨域设置xhrFields参数

    ajax跨越时默认不带cookie,如果需要带cookie调用,需要设置参数 xhrFields: { withCredentials: true },如: $.ajax({url : "h ...

  8. JS循环嵌套的执行原理

    [逆战班] 循环嵌套是指在一个循环语句中再定义一个循环语句的语法结构,外循环执行一次,内循环全部执行完,直到外循环执行完毕,整个循环结束. while.do.. while和for循环语句都可以进行嵌 ...

  9. docker报错Error response from daemon: driver failed programming external connectivity on endpoint *

    服务端 通常会显示 port xxx allocated的,意思就是 xxx 端口被占用了. 如果报port allocated端口占用,就docker ps 查看正使用的镜像,docker kill ...

  10. 使用JavaScript策略模式校验表单

    表单校验 Web项目中,登录,注册等等功能都需要表单提交,当把用户的数据提交给后台之前,前端一般要做一些力所能及的校验,比如是否填写,填写的长度,密码是否符合规范等等,前端校验可以避免提交不合规范的表 ...