using System; using System.Collections.Generic; using System.Linq; namespace CRM.Core.Common.EventBus { /// /// 事件总线 /// 发布与订阅处理逻辑 /// 核心功能代码 /// public class EventBus { private EventBus() { } private static EventBus _eventBus = null; private readonly object sync = new object(); /// /// 对于事件数据的存储,目前采用内存字典 /// private static Dictionary> eventHandlers = new Dictionary>(); /// // checks if the two event handlers are equal. if the event handler is an action-delegated, just simply // compare the two with the object.Equals override (since it was overriden by comparing the two delegates. Otherwise, // the type of the event handler will be used because we don't need to register the same type of the event handler // more than once for each specific event. /// private readonly Func eventHandlerEquals = (o1, o2) => { var o1Type = o1.GetType(); var o2Type = o2.GetType(); if (o1Type.IsGenericType && o1Type.GetGenericTypeDefinition() == typeof(ActionDelegatedEventHandler<>) && o2Type.IsGenericType && o2Type.GetGenericTypeDefinition() == typeof(ActionDelegatedEventHandler<>)) return o1.Equals(o2); return o1Type == o2Type; }; /// /// 初始化空的事件总件 /// public static EventBus Instance { get { return _eventBus ?? (_eventBus = new EventBus()); } } #region 事件订阅&取消订阅,可以扩展 /// /// 订阅事件列表 /// /// /// public void Subscribe(IEventHandler eventHandler) where TEvent : class, IEvent { lock (sync) { var eventType = typeof(TEvent); if (eventHandlers.ContainsKey(eventType)) { var handlers = eventHandlers[eventType]; if (handlers != null) { if (!handlers.Exists(deh => eventHandlerEquals(deh, eventHandler))) handlers.Add(eventHandler); } else { handlers = new List(); handlers.Add(eventHandler); } } else eventHandlers.Add(eventType, new List { eventHandler }); } } /// /// 订阅事件实体 /// /// /// public void Subscribe(Action eventHandlerFunc) where TEvent : class, IEvent { Subscribe(new ActionDelegatedEventHandler(eventHandlerFunc)); } public void Subscribe(IEnumerable> eventHandlers) where TEvent : class, IEvent { foreach (var eventHandler in eventHandlers) Subscribe(eventHandler); } /// /// 取消订阅事件 /// /// /// public void Unsubscribe(IEventHandler eventHandler) where TEvent : class, IEvent { lock (sync) { var eventType = typeof(TEvent); if (eventHandlers.ContainsKey(eventType)) { var handlers = eventHandlers[eventType]; if (handlers != null && handlers.Exists(deh => eventHandlerEquals(deh, eventHandler))) { var handlerToRemove = handlers.First(deh => eventHandlerEquals(deh, eventHandler)); handlers.Remove(handlerToRemove); } } } } public void Unsubscribe(IEnumerable> eventHandlers) where TEvent : class, IEvent { foreach (var eventHandler in eventHandlers) Unsubscribe(eventHandler); } public void Unsubscribe(Action eventHandlerFunc) where TEvent : class, IEvent { Unsubscribe(new ActionDelegatedEventHandler(eventHandlerFunc)); } #endregion #region 事件发布 /// /// 发布事件,支持异步事件 /// /// /// public void Publish(TEvent evnt) where TEvent : class, IEvent { if (evnt == null) throw new ArgumentNullException("evnt"); var eventType = evnt.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; eventHandler.Handle(evnt); } } else { WX.CRM.Common.LogHelper.Info("天真根本找不到!" + eventType.Name); } } public void Publish(TEvent evnt, Action callback, TimeSpan? timeout = null) where TEvent : class, IEvent { if (evnt == null) throw new ArgumentNullException("evnt"); var eventType = evnt.GetType(); if (eventHandlers.ContainsKey(eventType) && eventHandlers[eventType] != null && eventHandlers[eventType].Count > 0) { var handlers = eventHandlers[eventType]; try { foreach (var handler in handlers) { var eventHandler = handler as IEventHandler; eventHandler.Handle(evnt); callback(evnt, true, null); } } catch (Exception ex) { callback(evnt, false, ex); } } else callback(evnt, false, null); } #endregion } }