using System; using System.Collections.Generic; using System.Linq; namespace Blog.Core.EventBus { /// /// 基于内存 /// 事件总线订阅管理器 /// 单例模式 /// public partial class InMemoryEventBusSubscriptionsManager : IEventBusSubscriptionsManager { private readonly Dictionary> _handlers; private readonly List _eventTypes; public event EventHandler OnEventRemoved; public InMemoryEventBusSubscriptionsManager() { _handlers = new Dictionary>(); _eventTypes = new List(); } public bool IsEmpty => !_handlers.Keys.Any(); public void Clear() => _handlers.Clear(); /// /// 添加动态订阅 /// /// 约束:动态事件处理器接口 /// public void AddDynamicSubscription(string eventName) where TH : IDynamicIntegrationEventHandler { DoAddSubscription(typeof(TH), eventName, isDynamic: true); } /// /// 添加订阅 /// /// 约束:事件 /// 约束:事件处理器接口<事件> public void AddSubscription() where T : IntegrationEvent where TH : IIntegrationEventHandler { var eventName = GetEventKey(); DoAddSubscription(typeof(TH), eventName, isDynamic: false); if (!_eventTypes.Contains(typeof(T))) { _eventTypes.Add(typeof(T)); } } private void DoAddSubscription(Type handlerType, string eventName, bool isDynamic) { if (!HasSubscriptionsForEvent(eventName)) { _handlers.Add(eventName, new List()); } if (_handlers[eventName].Any(s => s.HandlerType == handlerType)) { throw new ArgumentException( $"Handler Type {handlerType.Name} already registered for '{eventName}'", nameof(handlerType)); } if (isDynamic) { _handlers[eventName].Add(SubscriptionInfo.Dynamic(handlerType)); } else { _handlers[eventName].Add(SubscriptionInfo.Typed(handlerType)); } } /// /// 移除动态订阅 /// /// /// public void RemoveDynamicSubscription(string eventName) where TH : IDynamicIntegrationEventHandler { var handlerToRemove = FindDynamicSubscriptionToRemove(eventName); DoRemoveHandler(eventName, handlerToRemove); } public void RemoveSubscription() where TH : IIntegrationEventHandler where T : IntegrationEvent { var handlerToRemove = FindSubscriptionToRemove(); var eventName = GetEventKey(); DoRemoveHandler(eventName, handlerToRemove); } private void DoRemoveHandler(string eventName, SubscriptionInfo subsToRemove) { if (subsToRemove != null) { _handlers[eventName].Remove(subsToRemove); if (!_handlers[eventName].Any()) { _handlers.Remove(eventName); var eventType = _eventTypes.SingleOrDefault(e => e.Name == eventName); if (eventType != null) { _eventTypes.Remove(eventType); } RaiseOnEventRemoved(eventName); } } } public IEnumerable GetHandlersForEvent() where T : IntegrationEvent { var key = GetEventKey(); return GetHandlersForEvent(key); } public IEnumerable GetHandlersForEvent(string eventName) => _handlers[eventName]; private void RaiseOnEventRemoved(string eventName) { var handler = OnEventRemoved; handler?.Invoke(this, eventName); } private SubscriptionInfo FindDynamicSubscriptionToRemove(string eventName) where TH : IDynamicIntegrationEventHandler { return DoFindSubscriptionToRemove(eventName, typeof(TH)); } /// /// 查询订阅并移除 /// /// /// /// private SubscriptionInfo FindSubscriptionToRemove() where T : IntegrationEvent where TH : IIntegrationEventHandler { var eventName = GetEventKey(); return DoFindSubscriptionToRemove(eventName, typeof(TH)); } private SubscriptionInfo DoFindSubscriptionToRemove(string eventName, Type handlerType) { if (!HasSubscriptionsForEvent(eventName)) { return null; } return _handlers[eventName].SingleOrDefault(s => s.HandlerType == handlerType); } public bool HasSubscriptionsForEvent() where T : IntegrationEvent { var key = GetEventKey(); return HasSubscriptionsForEvent(key); } public bool HasSubscriptionsForEvent(string eventName) => _handlers.ContainsKey(eventName); public Type GetEventTypeByName(string eventName) => _eventTypes.SingleOrDefault(t => t.Name == eventName); public string GetEventKey() { return typeof(T).Name; } } }