• 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();
            }
        }
    }
  • 相关阅读:
    171-滑动窗口问题
    170-133. 克隆图
    169-150. 逆波兰表达式求值
    windows相对路径设置与取消小工具[提效]
    Sword 38
    Sword 33
    Sword 28
    Sword 26
    Sword 12
    Sword 07
  • 原文地址:https://www.cnblogs.com/xietianjiao/p/7521682.html
Copyright © 2020-2023  润新知