通过在域模型中使用IoC来打破“无所不在的语言”?

时间:2013-12-27 06:30:27

标签: c# domain-driven-design ioc-container onion-architecture domain-events

我的问题是关于域事件的Udi's solution,特别是课程DomainEvents(请参阅下面的代码)

Udi代码的摘录。它将领域模型视为静态类。

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);
  }
} 

从上面的代码中,静态成员IContainer在域模型中创建了一个ioc-container-dependency。虽然我不确定Udi的IContainer是接口还是实际的IoC容器。

我的样本中没有看到这样的内容:

public interface IContainer
{
    IEnumerable<T> ResolveAll<T>();
}

我的第一个问题是: IContainer类中的这个DomainEvents是什么?如果它真的是一个IoC容器那么它就不会破坏“没有域中的基础设施”? (如果我错了,请纠正我)

DDD的想法是不是将基础设施与域分离?

我的第二个问题是: DomainEvents本身是否违反规则“无处不在的DDD语言” ?因为它的实现不属于任何域。

1 个答案:

答案 0 :(得分:3)

我同意,域名必须不了解基础设施,并且在某种程度上,Udi的解决方案提供了抽象。就个人而言,我更喜欢Mark Seemann在文章评论中提出的解决方案:通过界面注入事件聚合器。通过这种方式,事件可以作为一流的域模型公民,但通过最松散的耦合。