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 > 0)
            {
                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();
        }
    }
}
时间: 2024-10-15 02:05:54

C#事件の事件聚合器的相关文章

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

第一步:事件总线和事件聚合器 [1]事件总线 IEventBus IUnitOfWork.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Keasy5.Infrastructure { /// <summary> /// 表示所有集成于该接口的类型都是Unit Of Work的一种实现.

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

从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WPF(三)Prism-Region? 从PRISM开始学WPF(四)Prism-Module? 从PRISM开始学WPF(五)MVVM(一)ViewModel? 从PRISM开始学WPF(六)MVVM(二)Command? 从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator? Event aggregation. For communication acros

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

原文:从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator? 从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WPF(三)Prism-Region? 从PRISM开始学WPF(四)Prism-Module? 从PRISM开始学WPF(五)MVVM(一)ViewModel? 从PRISM开始学WPF(六)MVVM(二)Command? 从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggrega

js事件流、事件处理程序/事件侦听器

1.事件流 事件冒泡 IE的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档). 事件捕获 事件捕获的思想是不太具体的节点应该更早的接收到事件,而最具体的节点应该在最后接收到节点.事件捕获的用意在于事件到达预定目标之前捕获它. DOM事件流 “DOM2级事件流”规定的事件流包括三个阶段:事件捕获阶段.处于目标阶段和冒泡阶段.首先发生的是事件捕获,为截获事件提供了机会.然后是实际的目标接收到

Yarn源码分析之事件异步分发器AsyncDispatcher

AsyncDispatcher是Yarn中事件异步分发器,它是ResourceManager中的一个基于阻塞队列的分发或者调度事件的组件,其在一个特定的单线程中分派事件,交给AsyncDispatcher中之前注册的针对该事件所属事件类型的事件处理器EventHandler来处理.每个事件类型类可能会有多个处理渠道,即多个事件处理器,可以使用一个线程池调度事件.在Yarn的主节点ResourceManager中,就有一个Dispatcher类型的成员变量rmDispatcher,定义如下: pr

Android事件侦听器回调方法浅谈

http://developer.51cto.com/art/201001/180846.htm Android事件侦听器作为视图View类的接口,其中包含有不少回调方法,比如:onClick():onLongClick():onFocusChange():onKey():onTouch():onCreateContextMenu()等等. Android操作系统中,对于事件的处理是一个非常基础而且重要的操作.许多功能的实现都需要对相关事件进行触发才能达到自己的目的.比如Android事件侦听器

JavaScript事件---事件对象

原文:JavaScript事件---事件对象 发文不易,若转载传播,请亲注明出处,谢谢!   内容提纲: 1.事件对象 2.鼠标事件 3.键盘事件 4.W3C与IE JavaScript事件的一个重要方面是它们拥有一些相对一致的特点,可以给你的开发提供更多的强大功能.最方便和强大的就是事件对象,他们可以帮你处理鼠标事件和键盘敲击方面的情况,此外还可以修改一般事件的捕获/冒泡流的函数. 一.事件对象 事件处理函数的一个标准特性是,以某些方式访问的事件对象包含有关于当前事件的上下文信息. 事件处理三

js学习笔记:事件——事件流、事件处理程序、事件对象

Javascript与HTML之间的交互是通过事件实现的. 事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间. 可以使用侦听器来预定事件,以便事件发生时执行相应代码. 事件流 事件流描述的是从页面中接受事件的顺序. 事件冒泡 IE的事件流叫做事件冒泡,即事件开始是由最具体的元素接收,然后逐级向上传播到较为不具体的节点(文档). 如果点击了页面中的一个div元素,那么这个click事件可能会按照如下顺序传播: < div> < body> < html> docume

学习javascript中的事件——事件流

事件概念: HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件onclick.页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件.想要知道这些事件是在什么时候进行调用的,就需要了解一下“事件流”的概念. 什么是事件流? 事件流描述的是从页面中接收事件的顺序. 1.DOM事件流 “DOM2级事件”规定的事件流包括三个阶段: ① 事件捕获阶段: ② 处于目标阶段: ③ 事件冒泡阶段: 案例说明:页面中有一个id为btn的按钮,当点击这个按