C#事件の事件聚合器
事件聚合器用于集中管理事件的订阅(Subscribe)和处理(Handle),要使用事件聚合器,首先要理解:事件(event)本质上是一个类。
传统的+=和-=不足:
1、管理很麻烦;2、不方便扩展。
所以尝试使用事件聚合器来解决这个问题。
首先,使用一个统一的接口来实现事件的统一标记:
public interface IEvent{ }
事件,需要有对应的事件处理器(EventHandler),这里使用一个统一的接口 IEventHandler 来进行统一,IEventHandler 只包含一个处理事件的方法 Handle
public interface IEventHandler<in TEvent> where TEvent: class, IEvent
{
void Handler(TEvent @event);
}
事件聚合器接口 IEventAggregator 需要包含至少两个方法:订阅(Subscribe)和发布(Publish)
public interface IEventAggregator
{
void Subscribe<TEvent>(IEventHandler<TEvent> handler) where TEvent : class, IEvent;
void Publish<TEvent>(TEvent @event) where TEvent : class, IEvent;
}
接下来是实现这个接口:EventAggregator
举例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace EventAggregatorTest
{
public interface IEvent { } public interface IEventHandler<in TEvent> where TEvent : class, IEvent
{
void Handler(TEvent @event);
} public interface IEventAggregator
{
void Subscribe<TEvent>(IEventHandler<TEvent> handler) where TEvent : class, IEvent;
void Publish<TEvent>(TEvent @event) where TEvent : class, IEvent;
} public class EventAggregator : IEventAggregator
{
// 所有的 event 和 对应的 handler 都注册在这个字典里
private readonly Dictionary<Type, List<object>> _eventHandlers = new Dictionary<Type, List<object>>(); public void Subscribe<TEvent>(IEventHandler<TEvent> handler) where TEvent : class, IEvent
{
var eventType = typeof(TEvent);
if (_eventHandlers.ContainsKey(eventType))
{
var handlers = _eventHandlers[eventType];
if (handlers != null)
{
handlers.Add(handler);
}
else
{
handlers = new List<object> { handler };
}
}
else
{
_eventHandlers.Add(eventType, new List<object> { handler });
}
} public void Publish<TEvent>(TEvent @event) where TEvent : class, IEvent
{
var eventType = @event.GetType();
if (_eventHandlers.ContainsKey(eventType)
&& _eventHandlers[eventType] != null
&& _eventHandlers[eventType].Count > )
{
var handlers = _eventHandlers[eventType];
foreach (var handler in handlers)
{
var eventHandler = handler as IEventHandler<TEvent>;
eventHandler?.Handler(@event);
}
}
}
} public class MealDoneEvent : IEvent
{
public string DishName { get; private set; } public MealDoneEvent(string dishName)
{
DishName = dishName;
}
} public class MealDoneEventHandler : IEventHandler<MealDoneEvent>
{
private readonly string _name; public MealDoneEventHandler(string name)
{
_name = name;
} #region Implementation of IEventHandler<in MealDoneEvent> public void Handler(MealDoneEvent @event)
{
Console.WriteLine($"{_name} 正在 {@event.DishName}");
} #endregion
}
}
调用:
using EventAggregatorTest;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace EventAggregatorDemo
{
class Program
{
static void Main(string[] args)
{
var eventAggregator = new EventAggregator(); eventAggregator.Subscribe(new MealDoneEventHandler("张三"));
eventAggregator.Subscribe(new MealDoneEventHandler("李四"));
eventAggregator.Subscribe(new MealDoneEventHandler("王五")); eventAggregator.Publish(new MealDoneEvent("吃大餐")); Console.ReadKey();
}
}
}
C#事件の事件聚合器的更多相关文章
- 【DDD-Apwork框架】事件总线和事件聚合器
第一步:事件总线和事件聚合器 [1]事件总线 IEventBus IUnitOfWork.cs using System; using System.Collections.Generic; usin ...
- Prism的IEventAggregator事件聚合器, 事件订阅发布, ViewModel之间的通讯
WPF中时常会遇到ViewModel之间的通讯,ViewModel并不知道自己的View,但是一个View发生的更改需要通知另外一个View. 举一个例子,软件界面上有个人信息,打开一个界面更改用户的 ...
- 从PRISM开始学WPF(六)MVVM(三)事件聚合器EventAggregator?
从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WPF(三)Prism-Region? 从PRISM开始学WPF(四)Prism-Module? ...
- C#事件の事件聚合器(二)
WPF中时常会遇到ViewModel之间的通讯,ViewModel并不知道自己的View,但是一个View发生的更改需要通知另外一个View. 举一个例子,软件界面上有个人信息,打开一个界面更改用户的 ...
- Caliburn.Micro 杰的入门教程4,事件聚合器
Caliburn.Micro 杰的入门教程1(原创翻译)Caliburn.Micro 杰的入门教程2 ,了解Data Binding 和 Events(原创翻译)Caliburn.Micro 杰的入门 ...
- 从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator-更新至Prism7.1
原文:从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator-更新至Prism7.1 事件聚合器EventAggregator [7.1updated]除了app部分,没 ...
- 从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator?
原文:从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator? 从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WP ...
- .NET Core 3 WPF MVVM框架 Prism系列之事件聚合器
本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的使用事件聚合器实现模块间的通信 一.事件聚合器 在上一篇 .NET Core 3 WPF MVVM框架 Prism系列之模块化 ...
- C# prism 框架 MVVM框架 Prism系列之事件聚合器
网址:https://www.cnblogs.com/ryzen/p/12610249.html 本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的使用事件聚合器实现模块间的通信 ...
随机推荐
- 三角形(hdu1249)递推
三角形 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- Hibernate入门(二)——hibernateAPI详解
Hibernate API 详解 1.Configuration 功能:配置加载类,用于加载主配置,orm元数据加载 .创建: Configuration conf = new Configurati ...
- Redirect all output to file
That part is written to stderr, use 2> to redirect it. For example: foo > stdout.txt 2> std ...
- vue2.4+vue-cli+webpack history模式打包后 刷新404
开启HTML5 History Mode后,尤其需要server端的支持,官方文档里就有介绍:(传送门: https://router.vuejs.org/zh-cn/essentials/histo ...
- ATOM中MARKDOWN的使用小结
1.ctrl+shift+p ; 输入ssvvp ; 回车 2.输入markdown-preview进行安装 3.打开任意.md 文件 ; 按 ctrl-shift-m 进行预览
- loj#6030. 「雅礼集训 2017 Day1」矩阵(贪心 构造)
题意 链接 Sol 自己都不知道自己怎么做出来的系列 不难观察出几个性质: 最优策略一定是先把某一行弄黑,然后再用这一行去覆盖不是全黑的列 无解当且仅当无黑色.否则第一个黑色所在的行\(i\)可以先把 ...
- Mixing a dll boost library with a static runtime is a really bad idea错误的解决
作者:朱金灿 来源:http://blog.csdn.net/clever101 同事在使用boost库时遇到一个问题,在编译时出现一个错误:Mixing a dll boost library wi ...
- redis cluster是如何做到集两家之长的
站在读写分离的层次看redis的时候,redis和master和slave存在明显的主从关系,也就是说master处于管理状态,salve跟着大哥混,master给小弟slave发粮食[发送内存快照数 ...
- 性能测试 基于Python结合InfluxDB及Grafana图表实时采集Linux多主机或Docker容器性能数据
基于Python结合InfluxDB及Grafana图表实时采集Linux多主机性能数据 by:授客 QQ:1033553122 实现功能 1 测试环境 1 环境搭建 3 使用前提 3 使用方法 ...
- Html5 和 CSS的简单应用
本文是利用几个简单的小例子,来实现html+css的简单应用. 菱形链接菜单 本例是采用html5+css3.0设置的菜单链接.其中主要用到了以下几个方面: CSS3.0中的2D变换,如:旋转tran ...