///
///事件总线///发布与订阅处理逻辑///核心功能代码///
public classEventBus
{privateEventBus() { }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<>))returno1.Equals(o2);return o1Type ==o2Type;
};///
///初始化空的事件总件///
public staticEventBus Instance
{get{return _eventBus ?? (_eventBus = newEventBus());
}
}///
///通过XML文件初始化事件总线,订阅信自在XML里配置///
///
public staticEventBus InstanceForXml()
{if (_eventBus == null)
{
XElement root= XElement.Load(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EventBus.xml"));foreach (var evt in root.Elements("Event"))
{
List handlers = new List();
Type publishEventType= Type.GetType(evt.Element("PublishEvent").Value);foreach (var subscritedEvt in evt.Elements("SubscribedEvents"))foreach (var concreteEvt in subscritedEvt.Elements("SubscribedEvent"))
handlers.Add(Type.GetType(concreteEvt.Value));
eventHandlers[publishEventType]=handlers;
}
_eventBus= newEventBus();
}return_eventBus;
}#region 事件订阅&取消订阅,可以扩展
///
///订阅事件列表///
///
///
public void Subscribe(IEventHandlereventHandler)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);
}
}elseeventHandlers.Add(eventType,new List{ eventHandler });
}
}///
///订阅事件实体///
///
///
public void Subscribe(ActioneventHandlerFunc)where TEvent : class, IEvent
{
Subscribe(new ActionDelegatedEventHandler(eventHandlerFunc));
}public void Subscribe(IEnumerable>eventHandlers)where TEvent : class, IEvent
{foreach (var eventHandler ineventHandlers)
Subscribe(eventHandler);
}///
///取消订阅事件///
///
///
public void Unsubscribe(IEventHandlereventHandler)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 ineventHandlers)
Unsubscribe(eventHandler);
}public void Unsubscribe(ActioneventHandlerFunc)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 inhandlers)
{var eventHandler = handler as IEventHandler;if (eventHandler.GetType().IsDefined(typeof(HandlesAsynchronouslyAttribute), false))
{
Task.Factory.StartNew((o)=>eventHandler.Handle((TEvent)o), evnt);
}else{
eventHandler.Handle(evnt);
}
}
}
}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];
List tasks = new List();try{foreach (var handler inhandlers)
{var eventHandler = handler as IEventHandler;if (eventHandler.GetType().IsDefined(typeof(HandlesAsynchronouslyAttribute), false))
{
tasks.Add(Task.Factory.StartNew((o)=>eventHandler.Handle((TEvent)o), evnt));
}else{
eventHandler.Handle(evnt);
}
}if (tasks.Count > 0)
{if (timeout == null)
Task.WaitAll(tasks.ToArray());elseTask.WaitAll(tasks.ToArray(), timeout.Value);
}
callback(evnt,true, null);
}catch(Exception ex)
{
callback(evnt,false, ex);
}
}elsecallback(evnt,false, null);
}#endregion}