TG.WXCRM.V4/Core.Common/EventBus/EventBus.cs

196 lines
7.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
namespace CRM.Core.Common.EventBus
{
/// <summary>
/// 事件总线
/// 发布与订阅处理逻辑
/// 核心功能代码
/// </summary>
public class EventBus
{
private EventBus() { }
private static EventBus _eventBus = null;
private readonly object sync = new object();
/// <summary>
/// 对于事件数据的存储,目前采用内存字典
/// </summary>
private static Dictionary<Type, List<object>> eventHandlers = new Dictionary<Type, List<object>>();
/// <summary>
// 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.
/// </summary>
private readonly Func<object, object, bool> 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;
};
/// <summary>
/// 初始化空的事件总件
/// </summary>
public static EventBus Instance
{
get
{
return _eventBus ?? (_eventBus = new EventBus());
}
}
#region &
/// <summary>
/// 订阅事件列表
/// </summary>
/// <param name="type"></param>
/// <param name="subTypeList"></param>
public void Subscribe<TEvent>(IEventHandler<TEvent> 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<object>();
handlers.Add(eventHandler);
}
}
else
eventHandlers.Add(eventType, new List<object> { eventHandler });
}
}
/// <summary>
/// 订阅事件实体
/// </summary>
/// <param name="type"></param>
/// <param name="subTypeList"></param>
public void Subscribe<TEvent>(Action<TEvent> eventHandlerFunc)
where TEvent : class, IEvent
{
Subscribe<TEvent>(new ActionDelegatedEventHandler<TEvent>(eventHandlerFunc));
}
public void Subscribe<TEvent>(IEnumerable<IEventHandler<TEvent>> eventHandlers)
where TEvent : class, IEvent
{
foreach (var eventHandler in eventHandlers)
Subscribe<TEvent>(eventHandler);
}
/// <summary>
/// 取消订阅事件
/// </summary>
/// <param name="type"></param>
/// <param name="subType"></param>
public void Unsubscribe<TEvent>(IEventHandler<TEvent> 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<TEvent>(IEnumerable<IEventHandler<TEvent>> eventHandlers)
where TEvent : class, IEvent
{
foreach (var eventHandler in eventHandlers)
Unsubscribe<TEvent>(eventHandler);
}
public void Unsubscribe<TEvent>(Action<TEvent> eventHandlerFunc)
where TEvent : class, IEvent
{
Unsubscribe<TEvent>(new ActionDelegatedEventHandler<TEvent>(eventHandlerFunc));
}
#endregion
#region
/// <summary>
/// 发布事件,支持异步事件
/// </summary>
/// <typeparam name="TEvent"></typeparam>
/// <param name="evnt"></param>
public void Publish<TEvent>(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<TEvent>;
eventHandler.Handle(evnt);
}
}
else
{
WX.CRM.Common.LogHelper.Info("天真根本找不到!" + eventType.Name);
}
}
public void Publish<TEvent>(TEvent evnt, Action<TEvent, bool, Exception> 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<TEvent>;
eventHandler.Handle(evnt);
callback(evnt, true, null);
}
}
catch (Exception ex)
{
callback(evnt, false, ex);
}
}
else
callback(evnt, false, null);
}
#endregion
}
}