事件聚合器用于集中管理事件的订阅(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#事件の事件聚合器的更多相关文章

  1. 【DDD-Apwork框架】事件总线和事件聚合器

    第一步:事件总线和事件聚合器 [1]事件总线 IEventBus IUnitOfWork.cs using System; using System.Collections.Generic; usin ...

  2. Prism的IEventAggregator事件聚合器, 事件订阅发布, ViewModel之间的通讯

    WPF中时常会遇到ViewModel之间的通讯,ViewModel并不知道自己的View,但是一个View发生的更改需要通知另外一个View. 举一个例子,软件界面上有个人信息,打开一个界面更改用户的 ...

  3. 从PRISM开始学WPF(六)MVVM(三)事件聚合器EventAggregator?

    从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WPF(三)Prism-Region? 从PRISM开始学WPF(四)Prism-Module? ...

  4. C#事件の事件聚合器(二)

    WPF中时常会遇到ViewModel之间的通讯,ViewModel并不知道自己的View,但是一个View发生的更改需要通知另外一个View. 举一个例子,软件界面上有个人信息,打开一个界面更改用户的 ...

  5. Caliburn.Micro 杰的入门教程4,事件聚合器

    Caliburn.Micro 杰的入门教程1(原创翻译)Caliburn.Micro 杰的入门教程2 ,了解Data Binding 和 Events(原创翻译)Caliburn.Micro 杰的入门 ...

  6. 从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator-更新至Prism7.1

    原文:从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator-更新至Prism7.1 事件聚合器EventAggregator [7.1updated]除了app部分,没 ...

  7. 从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator?

    原文:从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator? 从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WP ...

  8. .NET Core 3 WPF MVVM框架 Prism系列之事件聚合器

    本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的使用事件聚合器实现模块间的通信 一.事件聚合器  在上一篇 .NET Core 3 WPF MVVM框架 Prism系列之模块化 ...

  9. C# prism 框架 MVVM框架 Prism系列之事件聚合器

    网址:https://www.cnblogs.com/ryzen/p/12610249.html 本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的使用事件聚合器实现模块间的通信 ...

随机推荐

  1. [android] 测试的相关概念

    /********************2016年5月4日 更新********************************/ 知乎:如何专业地进行黑盒测试? 之前遇到过有些黑盒测试人员,感觉他 ...

  2. php中的implements 使用详解

    php类中接口的应用关键字是interface.implements了,接口是一种成员属性全部为抽象或常量的特殊抽象类,implements主要是对类名,类所拥有的方法,以及所传参数起约束和规范做用, ...

  3. Mac下安装最新版本的Graphviz

    由于版本兼容问题,Mac下Graphviz之前一直装的是低版本的2.36.高版本的安装方法如下: 1.log in & download Xcode an Xcode Command Line ...

  4. Mysql中的外键分析(什么是外键,为什么要用外键,添加外键,主外键关联删除)

    有一个东西一直在我脑海中是个很烦的东西,但是这东西不搞清楚会阻碍自己的前进.自己做项目demo永远只能用一张表... 所以今天还是学习了下外键希望能够搞明白一些... 百度上搜索外键的作用" ...

  5. POJ2155(二维树状数组)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17226   Accepted: 6461 Descripti ...

  6. web-worker 的使用

    JavaScript采用的是单线程模式,它每次也只能执行一个事件,所以它在加载大量的事件的时候会比较慢. 而web-worker的作用就是给JavaScript提供一个多线程的模式. 注意的是 web ...

  7. Android dp、dip、dpi、px、sp简介及相关换算,及其应用实例

    屏幕分辨率:在x y轴上的像素点数.单位是px,1px=1个像素点.一般以    纵向像素×横向像素    表示,如1920*1080dpi--------------------------每英寸上 ...

  8. 产品经理说| AIOps 让告警变得更智能 (下)

    AIOps 人工智能和IT运营支撑 Ops 之间的故事,愈演愈烈,已经成为当今运维圈的热门话题,我打算从2篇文档分享我们在 AIOps 上一些探索和实践.(上篇)主要介绍了为什么事件(告警)处理需要 ...

  9. python datetime object 去除毫秒(microsecond)

    >>>import datetime >>>d = datetime.datetime.now().replace(microsecond=0) >>& ...

  10. [20181031]12c 在线移动数据文件.txt

    [20181031]12c 在线移动数据文件.txt --//12c以前,移动或者改名数据文件是一项比较麻烦的事情,至少要停一下业务.而12c支持在线移动或者改名数据文件,并且有点不可思议--//的是 ...