/src/Extensions/SimpleCqrs.NServiceBus.Core/Eventing/NsbLocalEventBus.cs
C# | 101 lines | 87 code | 14 blank | 0 comment | 5 complexity | e3472fd60345d0b892ae1d81f9470cfd MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using log4net;
- using SimpleCqrs.Eventing;
-
- namespace SimpleCqrs.NServiceBus.Eventing
- {
- internal class NsbLocalEventBus : IEventBus
- {
- private readonly IDomainEventHandlerFactory eventHandlerBuilder;
- private IDictionary<Type, EventHandlerInvoker> eventHandlerInvokers;
-
- public NsbLocalEventBus(IEnumerable<Type> eventHandlerTypes, IDomainEventHandlerFactory eventHandlerBuilder)
- {
- this.eventHandlerBuilder = eventHandlerBuilder;
- BuildEventInvokers(eventHandlerTypes);
- }
-
- public void PublishEvent(DomainEvent domainEvent)
- {
- if(!eventHandlerInvokers.ContainsKey(domainEvent.GetType())) return;
-
- var eventHandlerInvoker = eventHandlerInvokers[domainEvent.GetType()];
- eventHandlerInvoker.Publish(domainEvent);
- }
-
- public void PublishEvents(IEnumerable<DomainEvent> domainEvents)
- {
- foreach(var domainEvent in domainEvents)
- PublishEvent(domainEvent);
- }
-
- private void BuildEventInvokers(IEnumerable<Type> eventHandlerTypes)
- {
- eventHandlerInvokers = new Dictionary<Type, EventHandlerInvoker>();
- foreach(var eventHandlerType in eventHandlerTypes)
- {
- foreach(var domainEventType in GetDomainEventTypes(eventHandlerType))
- {
- EventHandlerInvoker eventInvoker;
- if(!eventHandlerInvokers.TryGetValue(domainEventType, out eventInvoker))
- eventInvoker = new EventHandlerInvoker(eventHandlerBuilder, domainEventType);
-
- eventInvoker.AddEventHandlerType(eventHandlerType);
- eventHandlerInvokers[domainEventType] = eventInvoker;
- }
- }
- }
-
- private static IEnumerable<Type> GetDomainEventTypes(Type eventHandlerType)
- {
- return from interfaceType in eventHandlerType.GetInterfaces()
- where interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IHandleDomainEvents<>)
- select interfaceType.GetGenericArguments()[0];
- }
-
- private class EventHandlerInvoker
- {
- private readonly IDomainEventHandlerFactory eventHandlerFactory;
- private readonly Type domainEventType;
- private readonly List<Type> eventHandlerTypes;
- private readonly ILog logger = LogManager.GetLogger(typeof(NsbLocalEventBus));
-
- public EventHandlerInvoker(IDomainEventHandlerFactory eventHandlerFactory, Type domainEventType)
- {
- this.eventHandlerFactory = eventHandlerFactory;
- this.domainEventType = domainEventType;
- eventHandlerTypes = new List<Type>();
- }
-
- public void AddEventHandlerType(Type eventHandlerType)
- {
- eventHandlerTypes.Add(eventHandlerType);
- }
-
- public void Publish(DomainEvent domainEvent)
- {
- var exceptionList = new List<Exception>();
-
- var handleMethod = typeof(IHandleDomainEvents<>).MakeGenericType(domainEventType).GetMethod("Handle");
- foreach(var eventHandlerType in eventHandlerTypes)
- {
- try
- {
- var eventHandler = eventHandlerFactory.Create(eventHandlerType);
- handleMethod.Invoke(eventHandler, new object[] {domainEvent});
- }
- catch(Exception exception)
- {
- logger.Error(string.Format("An exception occured while handling event of type '{0}'\nMessage: {1}", domainEvent.GetType(), exception.Message), exception);
- exceptionList.Add(exception);
- }
- }
-
- if(exceptionList.Count > 0)
- throw new AggregateException(exceptionList);
- }
- }
- }
- }