Domain Events with Ninject and ASP.Net Web API | Contented Coder Blog
该博客谈论了使用Ninject依赖注射的方法实现领域事件,个人认为这与DCI实现方式非常类似,都是结构上组合。
假设Domain events代码如下:
public static class DomainEvents { /// <summary> /// The _actions. /// </summary> /// <remarks>Marked as ThreadStatic that each thread has its own callbacks</remarks> [ThreadStatic] private static List<Delegate> _actions;
/// <summary> /// The container /// </summary> public static IEventContainer Container;
/// <summary> /// Registers the specified callback for the given domain event. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="callback">The callback.</param> public static void Register<T>(Action<T> callback) where T : IDomainEvent { if (_actions == null) _actions = new List<Delegate>();
_actions.Add(callback); } /// <summary> /// Raises the specified domain event and calls the event handlers. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="domainEvent">The domain event.</param> public static void Raise<T>(T domainEvent) where T : IDomainEvent { if (Container != null) foreach (var handler in Container.Handlers(domainEvent)) handler.Handle(domainEvent);
// registered actions, typically used for unit tests. if (_actions != null) foreach (var action in _actions) if (action is Action<T>) ((Action<T>)action)(domainEvent); } }
|
其中IEventContainer是一个接口:
public interface IEventContainer { IEnumerable<IDomainEventHandler<T>> Handlers<T>(T domainEvent) where T : IDomainEvent; }
|
IEventContainer的NInject实现代码如下:
public class NinjectEventContainer : IEventContainer { private readonly IKernel _kernerl;
public NinjectEventContainer(IKernel kernal) { _kernerl = kernal; }
public IEnumerable<IDomainEventHandler<T>> Handlers<T>(T domainEvent) where T : IDomainEvent { return _kernerl.GetAll<IDomainEventHandler<T>>(); } }
|
这个实现依赖于DI核心IKernerl,关键的代码如下:
private static IKernel CreateKernel() { var kernel = new StandardKernel(); kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel); kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
// this is our concrete implementation of handler for winner selected event kernel.Bind<IDomainEventHandler<WinnerSelectedEvent>>().To<WinnerSelectedHandler>();
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
// <strong> WIRE UP DOMAIN EVENTS CONTAINER </strong> DomainEvents.Container = new NinjectEventContainer(kernel);
return kernel; }
|