使用Ninject和Udi Dahan的域事件

时间:2012-10-22 16:16:07

标签: asp.net-mvc dependency-injection inversion-of-control ninject domain-events

我在MVC项目中使用Ninject,并尝试按照Udi Dahan的模式实现域事件http://www.udidahan.com/2009/06/14/domain-events-salvation/

在下面的摘录中,“容器”用于解析已经引发的特定事件类型的所有事件处理程序。

我的问题(如果我遗漏了一些基本内容,请道歉)是如何使用Ninject做到这一点的?换句话说:

  1. 如何在此静态类中设置“容器”?

  2. 一旦我有了一个容器(内核?),解决所有事件处理程序的Ninject语法是什么(我假设我必须先在服务模块中注册)?

  3. 我继续在帖子中读到只应该使用构造函数注入,并且从那里递归地解决所有内容,并且访问Ninject内核是禁止的。因此,非常感谢任何有关如何做到这一点的建议。

    摘自文章

    public static class DomainEvents
    { 
      [ThreadStatic] //so that each thread has its own callbacks
      private static List<Delegate> actions; 
    
      public static IContainer Container { get; set; } //as before
    
      //Registers a callback for the given domain event
      public static void Register<T>(Action<T> callback) where T : IDomainEvent
      {
         if (actions == null)
            actions = new List<Delegate>();
    
         actions.Add(callback);
     }
    
     //Clears callbacks passed to Register on the current thread
     public static void ClearCallbacks ()
     {
         actions = null;
     }
    
     //Raises the given domain event
     public static void Raise<T>(T args) where T : IDomainEvent
     {
        if (Container != null)
           foreach(var handler in Container.ResolveAll<Handles<T>>())
              handler.Handle(args);
    
        if (actions != null)
            foreach (var action in actions)
                if (action is Action<T>)
                    ((Action<T>)action)(args);
     }
    }
    

1 个答案:

答案 0 :(得分:6)

  

如何在此静态类中设置“容器”?

您必须在应用程序启动期间设置它:

DomainEvents.Container = kernel;
  

解决所有事件处理程序的Ninject语法是什么:

你可以这样做,例如:

Container.Get<IEnumerable<Handles<T>>>())

Udi的静态DomainEvents类是 Ambient Context 反模式的实现(参见DI PP&P5.3)。在这种情况下,我宁愿使用依赖注入将IDomainEvents抽象注入到需要它的代码中,而不是让代码依赖于静态实例。

但问题是你的域对象需要依赖IDomainEvents,并且(可能)构造函数注入是不可能的。诀窍是在这种情况下使用方法注入。

换句话说,使用构造函数注入将IDomainEvents注入命令处理程序或服务(或者您所谓的业务逻辑中使用域对象上的方法)并将该依赖项传递给域对象调用需要它的方法(方法注入)。