美文网首页
C# 一套事件系统,全局监听、发送、接收、移除事件

C# 一套事件系统,全局监听、发送、接收、移除事件

作者: 洒一地阳光_217d | 来源:发表于2020-10-12 14:12 被阅读0次

    事件系统主要通过单例事件管理器:EventManager和事件参数:EventArgs(可以是任意类型),来进行事件的监听、发送、接收、移除。

    分为以下模块:

    • IEventListener:事件监听者,由需要监听事件的对象继承;
    • IEventArgs,EventArgs,EventArgsExtend:事件参数;
    • EventManager:负责事件监听、派送、移除;
    • IEventHub,EventHub:封装事件监听、派送、移除功能实现的具体逻辑;

    事件系统分为两部分:使用方法实现代码(说明讲解都在注释里):

    一、使用方法:

    使用时只需要使用EventManager、IEventListener、EventArgs即可:

    /// <summary>
    /// 事件Id
    /// </summary>
    public class EventId
    {
        public const int Open = 100;
        public const int Close = 101;
        public const int Message = 102;
    }
    
    /// <summary>
    /// 测试消息
    /// </summary>
    public class TestMsg
    {
        public int MsgId;
        public string Msg;
    }
    
    public class ClassA
    {
        public void DoTest()
        {
            // 发送 Open 事件,传递参数为string类型
            IEventArgs arg1 = EventArgs<string>.CreateEventArgs("打开");
            EventManager.Instance.Dispatch(EventId.Open, arg1);
    
    
            // 发送 Close 事件,传递参数为值类型:int
            IEventArgs arg2 = EventArgs<int>.CreateEventArgs(999);
            EventManager.Instance.Dispatch(EventId.Close, arg2);
    
    
            // 发送 Message 事件,传递参数为引用类型:class
            TestMsg value = new TestMsg()
            {
                MsgId = 888,
                Msg = "一条广告"
            };
            IEventArgs arg3 = EventArgs<TestMsg>.CreateEventArgs(value);
            EventManager.Instance.Dispatch(EventId.Message, arg3);
        }
    }
    
    // 继承IEventListener,接收事件
    public class ClassB : IEventListener
    {
        public void OnEnable()
        {
            // 监听事件
            EventManager.Instance.AddListener(EventId.Open, this);
            EventManager.Instance.AddListener(EventId.Close, this);
            EventManager.Instance.AddListener(EventId.Message, this);
        }
    
        public void OnDisable()
        {
            // 移除事件
            EventManager.Instance.RemoveListener(EventId.Open, this);
            EventManager.Instance.RemoveListener(EventId.Close, this);
            EventManager.Instance.RemoveListener(EventId.Message, this);
        }
    
        // 处理事件
        public void HandleEvent(int eventId, IEventArgs args)
        {
            switch (eventId)
            {
                case EventId.Open:
                    string value1 = args.GetValue<string>(); // "打开"
                    break;
    
                case EventId.Close:
                    int value2 = args.GetValue<int>(); // 999
                    break;
    
                case EventId.Message:
                    TestMsg value3 = args.GetValue<TestMsg>();
                    // value3.MsgId 888
                    // value3.Msg "一条广告"
                    break;
    
                default:
                    break;
            }
        }
    }
    
    二、事件系统代码实现:

    分为以下模块:

    • IEventListener:事件监听者,由需要监听事件的对象继承;
    • IEventArgs,EventArgs,EventArgsExtend:事件参数;
    • EventManager:负责事件监听、派送、移除;
    • IEventHub,EventHub:事件监听、派送、移除功能实现的具体逻辑;
    IEventListener:事件监听者,由需要监听事件的对象继承;
    /// <summary>
    /// 事件监听者
    /// </summary>
    public interface IEventListener
    {
        void HandleEvent(int eventId, IEventArgs args);
    }
    
    IEventArgs,EventArgs,EventArgsExtend:事件参数;
    public interface IEventArgs
    {
    }
    
    /// <summary>
    /// 事件参数
    /// 可以是值类型,也可以是引用类型
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class EventArgs<T> : IEventArgs
    {
        public T arg;
    
        /// <summary>
        /// 创建事件参数
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static IEventArgs CreateEventArgs(T val)
        {
            return new EventArgs<T>(val);
        }
    
        private EventArgs(T arg)
        {
            this.arg = arg;
        }
    }
    
    /// <summary>
    /// 事件参数扩展
    /// </summary>
    public static class EventArgsExtend
    {
        /// <summary>
        /// 获取事件参数值
        /// </summary>
        /// <param name="args"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetValue<T>(this IEventArgs args)
        {
            T result = default(T);
            if (args is EventArgs<T>)
            {
                result = ((EventArgs<T>)args).arg;
            }
            return result;
        }
    }
    
    EventManager:负责事件监听、派送、移除;
    /// <summary>
    /// 单例事件管理器,负责事件监听、派送、移除
    /// </summary>
    public class EventManager
    {
        public static EventManager Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new EventManager();
                }
    
                return _instance;
            }
        }
    
        private static EventManager _instance;
    
        private IEventHub _eventHub;
    
        public EventManager()
        {
            this._eventHub = new EventHub();
        }
    
        /// <summary>
        /// 添加监听事件
        /// </summary>
        /// <param name="eventId"></param>
        /// <param name="listener"></param>
        public void AddListener(int eventId, IEventListener listener)
        {
            this._eventHub.AddListener(eventId, listener);
        }
    
        /// <summary>
        /// 发送事件
        /// </summary>
        /// <param name="eventId"></param>
        /// <param name="args">事件参数可通过 EventArgs.CreateEventArgs 创建</param>
        public void Dispatch(int eventId, IEventArgs args = null)
        {
            this._eventHub.Dispatch(eventId, args);
        }
    
        /// <summary>
        /// 移除监听事件
        /// </summary>
        /// <param name="eventId"></param>
        /// <param name="listener"></param>
        public void RemoveListener(int eventId, IEventListener listener)
        {
            this._eventHub.RemoveListener(eventId, listener);
        }
    }
    
    IEventHub,EventHub:封装事件监听、派送、移除功能实现的具体逻辑;
    public interface IEventHub
    {
        void AddListener(int eventId, IEventListener listener);
    
        void RemoveListener(int eventId, IEventListener listener);
    
        void Dispatch(int eventId, IEventArgs args);
    }
    
    using System.Collections.Generic;
    
    public class EventHub : IEventHub
    {
        private Dictionary<int, List<IEventListener>> _eventDic = new Dictionary<int, List<IEventListener>>();
    
        public void AddListener(int eventId, IEventListener listener)
        {
            if (this._eventDic == null)
            {
                return;
            }
    
            List<IEventListener> list = null;
            this._eventDic.TryGetValue(eventId, out list);
            if (list == null)
            {
                list = new List<IEventListener>();
                this._eventDic[eventId] = list;
            }
            list.Add(listener);
        }
    
        public void RemoveListener(int eventId, IEventListener listener)
        {
            if (this._eventDic == null)
            {
                return;
            }
    
            List<IEventListener> list = null;
            this._eventDic.TryGetValue(eventId, out list);
            if (list != null && list.Contains(listener))
            {
                list.Remove(listener);
            }
        }
    
        public void Dispatch(int eventId, IEventArgs args)
        {
            if (this._eventDic == null)
            {
                return;
            }
    
            List<IEventListener> list = null;
            this._eventDic.TryGetValue(eventId, out list);
            if (list == null || list.Count <= 0)
            {
                return;
            }
    
            for (int i = 0; i < list.Count; i++)
            {
                IEventListener eventListener = list[i];
                if (eventListener != null)
                {
                    eventListener.HandleEvent(eventId, args);
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:C# 一套事件系统,全局监听、发送、接收、移除事件

          本文链接:https://www.haomeiwen.com/subject/kdwupktx.html