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的使用事件聚合器实现模块间的通信 ...
随机推荐
- SQL语句NOT IN优化之换用NOT EXISTS
NOT IN查询示例(示例背景描述:根据条件查询Questions表得到的数据基本在PostedData表中不存在,为完全保证查询结果在PostedData表中不存在,使用NOT IN): SET S ...
- C#基础知识总结(七)
摘要 C#最简单的两个算法:输入数字打印出菱形星星.冒泡排序1.输入数字打印出菱形星星 static void Main(string[] args) { //输入一个数,表示菱形星号,数字必须是一个 ...
- Centos 6.8 定时任务Crontab服务
一,crontab服务的简介 二.安装cron服务 安装cron服务 : --yum install vixie-cron --yum install crontabs 检出cron服务 检查cron ...
- MySQL技巧(二)——无限级分类表设计
无限级分类表的设计(掌握'自身连接') 类似图书这种,会有很多种分类,而且在现实生活中这种分类会无限的往下分,所以不可能每有一个分类就创建一个分类表.应该使用下面这种语句 DROP TABLE IF ...
- js循环json得到 键和值
var jsondata=[{"男":4,"女":3,"不详":0},{"男one":23,"女two&quo ...
- 替换富文本里的px为rem
var content = '23px' content = content.replace(/(\d+)px/g, function(s, t) { s = s.replace('px', ''); ...
- CSS3布局之多列布局columns详解
columns语法:columns:[ column-width ] || [ column-count ]设置或检索对象的列数和每列的宽度 其中:[ column-width ]:设置或检索对象每列 ...
- springboot Redis 缓存
1,先整合 redis 和 mybatis 步骤一: springboot 整合 redis 步骤二: springboot 整合 mybatis 2,启动类添加 @EnableCaching 注解, ...
- Nginx 参数配置相关
Nginx参数配置相关 by:授客 QQ:1033553122 目的: 对Nginx配置的点滴学习总结,主要目的在于分析Nginx与性能相关的一些参数设置,以便性能调优时选择最优配置 环境: $ ...
- Testlink1.9.17使用方法(第五章 测试用例管理)
第五章 测试用例管理 QQ交流群:585499566 TestLink支持的测试用例的管理包含二层:分别为新建测试用例集(Test Suites).创建测试用例(Test Cases).可以把测试用例 ...