Problem:
in my domain layer assembly I store two interfaces:
public interface IDomainEvent { }
and
public interface IHandle<T> where T: IDomainEvent, new()
EventDispatcher class is defined there also:
public static class EventDispatcher {
[ThreadStatic]
private static List<Delegate> actions;
[ThreadStatic]
private static List<Object> handlers;
public static List<Object> Handlers {
get { return handlers; }
set { handlers = value; }
}
public static void Register<T>(Action<T> callback) where T : IDomainEvent, new() {
if(null == actions) {
actions = new List<Delegate>();
actions.Add(callback);
}
}
public static void ClearCallbacks() {
actions = null;
}
public static void Raise<T>(T @event) where T : IDomainEvent, new() {
if(null != Handlers) {
foreach(var handler in Handlers.Where(h => h is IHandle<T>)) {
((IHandle<T>)handler).Handle(@event);
}
}
if(null != actions) {
foreach(var action in actions) {
if(action is Action<T>) {
((Action<T>)action)(@event);
}
}
} // if(null != actions) {
}
}
There’s a module in presentation layer assembly:
public class EventDispatchingModule : NinjectModule {
public override void Load() {
// EventDispatcher.Handlers = this.Kernel.GetAll(IHandle<T>); Can't do that!
// Bind<IHandle<CarHasBeenRegisteredEvent>>().To<CarHasBeenRegisteredHandler();
}
}
So I can’t call Kernel.GetAll(IHandle<T>) there because it can’t resolve T parameter.
Howcome I resolve this?
Thanks!
No need to use a module (I’ve not used ninject, but something similar):
But I don’t know how ninject handles scoped objects (which may also want to receive the events).
My container has domain events built in, read more in this article: http://www.codeproject.com/Articles/440665/Having-fun-with-Griffin-Container
Update:
I’ve updated the code sample to make the domain project unaware of Ninject.
You are not using Service Location with this code. The internals of the event dispatcher is. i.e. none of your code is affected by it.