For a project I'm working on, we're practicing domain driven design and using ninject as our IOC container. I'm trying to implement domain events similar to the approach described by Tony Truong here. I'm trying to use ninject without having to have a static service or referencing the Kernel outside the composition root. I'm trying to do something like this
/// <summary>
/// Service to dispatch domain events to handlers.
/// </summary>
public class NinjectDomainEventDispatcher : IDomainEventDispatcher
{
/// <summary>
/// Array containing domain event handler registrations.
/// </summary>
private readonly IDomainEventHandler<IDomainEvent>[] _handlers;
/// <summary>
/// Initializes a new instance of the <see cref="NinjectDomainEventDispatcher"/> class.
/// </summary>
/// <param name="handlers">Registered domain event handlers.</param>
public NinjectDomainEventDispatcher(IDomainEventHandler<IDomainEvent>[] handlers)
{
_handlers = handlers;
}
/// <summary>
/// Dispatch domain event to subscribed handlers.
/// </summary>
/// <typeparam name="T">Type of domain event to dispatch.</typeparam>
/// <param name="domainEvent">Domain event to dispatch.</param>
public void Dispatch<T>(T domainEvent) where T : IDomainEvent
{
foreach (var handler in _handlers.Where(x => x.GetType() == typeof(IDomainEventHandler<T>)))
{
handler.Handle(domainEvent);
}
}
}
/// <summary>
/// Module that will be used for the registration of the domain event handlers
/// </summary>
public class DomainEventHandlerModule : NinjectModule
{
/// <summary>
/// The method that will be used to load the ninject registration information.
/// </summary>
public override void Load()
{
Bind<IDomainEventDispatcher>().To<NinjectDomainEventDispatcher>();
Bind<IDomainEventHandler<ConcreteDomainEvent>>().To<ConcreteDomainEventHandler1>();
Bind<IDomainEventHandler<ConcreteDomainEvent>>().To<ConcreteDomainEventHandler2>();
Bind<IDomainEventHandler<AnotherConcreteDomainEvent>>().To<AnotherConcreteDomainEventHandler1>();
Bind<IDomainEventHandler<AnotherConcreteDomainEvent>>().To<AnotherConcreteDomainEventHandler2>();
}
}
The goal is to call all handlers registered for the type of the domain event instance passed in to the Dispatch method. My problem is, the handlers array is empty when injected (I'm guessing because it's specifically looking for handlers bound to IDomainEventHandler<IDomainEvent>, not all handlers of types implementing IDomainEvent like I need).