java ddd 事件总线_DDD~领域事件与事件总线

本文介绍了Java中基于领域驱动设计(DDD)的事件总线实现,包括事件存储方式、事件处理逻辑以及如何订阅和发布事件。通过示例代码展示了如何使用事件总线进行事件订阅、取消订阅和发布,支持同步和异步处理。
摘要由CSDN通过智能技术生成

///

///事件总线///发布与订阅处理逻辑///核心功能代码///

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}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值