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的使用事件聚合器实现模块间的通信 ...
随机推荐
- vs 调试 iis中的网站
打开网站,在vs中附加进程,选择w3wp.exe,如果不能下断点,设置一下pdb文件位置
- 【Zookeeper】windows环境下zookeeper安装
下载 Apache官方最新版本为:3.4.12 下载地址:https://mirrors.cnnic.cn/apache/zookeeper/zookeeper-3.4.12/ 安装 解压到指定目录 ...
- C#设计模式之六适配器模式(Adapter Pattern)【结构型】
一.引言 从今天开始我们开始讲[结构型]设计模式,[结构型]设计模式有如下几种:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式.[创建型]的设计模式解决的是对象创建的问题,那[ ...
- SqlHelper模板
在实际开发中,我们不会直接使用拼写SQL语句的方法进行数据库操作,而是使用参数化的方法进行数据库操作,这样做的好处很多,不仅提高了程序的健壮性,同时也避免的SQL注入的问题.在这里,笔者为初学者提供一 ...
- NPOI 读取Excel文件
private void buttonExcel_Click(object sender, EventArgs e) { FileStream fs = null; List<ISheet> ...
- HTML DOM classList 属性
页面DOM里的每个节点上都有一个classList对象,程序员可以使用里面的方法新增.删除.修改节点上的CSS类.使用classList,程序员还可以用它来判断某个节点是否被赋予了某个CSS类. 添加 ...
- 洛谷P4723 【模板】线性递推(多项式取模 线性代数)
题意 题目链接 Sol Orz shadowice 注意,下面的代码自带O(随时TLE)倍大常数.. #include<bits/stdc++.h> #define Pair pair&l ...
- js调用摄像头
详情源码请参见下方的 GitHub !!! <div> <b>调用移动端摄像头</b><br> <label>照相机: <input ...
- Nginx 集群 反向代理多个服务器
准备多个服务器,使用 nginx 先做好代理(我这里只有一台服务器,就拷贝两个 tomcat 了,端口分别设置为 8081 和 8082) 1,复制 tomcat cp -r apache-tomca ...
- springboot 学习之路 3( 集成mybatis )
目录:[持续更新.....] spring 部分常用注解 spring boot 学习之路1(简单入门) spring boot 学习之路2(注解介绍) spring boot 学习之路3( 集成my ...