域事件处理程序和数据库更改事件

时间:2015-03-23 09:43:51

标签: design-patterns domain-driven-design cqrs

我是Domain Driven和CQRS的新手,并且对事件处理程序机制感到困惑。

Domian事件正在触发事件。例如,创建了一个帐户。

public class Account: AggregateRoot{        
      public Account(Guid id)
      {
          Apply(new AccountCreatedEvent { AggregateRootId = id });
      }
}
public class AccountCratedEvent: DomainEvent{
}

我认为这是Domain的内部事件机制。所以我无法向新帐户所有者发送电子邮件。因为新帐户尚未保存到数据库。那么我应该创建一个新的事件处理程序来在数据库节省后填充吗?

2 个答案:

答案 0 :(得分:0)

是的,这是一个常见的问题。根据您域名的确切性质,您可能希望选择2个可能的位置之一来发送电子邮件:

最简单的放置方式是作为事件处理程序。这假设了一些事情:

  • 所有事件处理程序是否成功完成无关紧要
  • 事件和/或读取模型具有发送消息所需的所有信息。重要的是,读取模型不依赖于更新的完成(最终的一致性问题)。
  • 您的邮件发送基础设施很简单

如果有任何问题,那么您需要使用Process Manager。这是一个可以侦听事件和发出命令的设备。在这种情况下,成功完成所有事件后,发出命令以发送电子邮件。

我写了一篇更详细的博文,内容涉及这个主题。您可以在此处阅读:How to Send Emails the Right Way in a CQRS System

答案 1 :(得分:0)

Apply()事件并不等于立即将其发送出去,尽管您的域模型会立即处理事件,如:

public class Account: AggregateRoot{        
    public Account(Guid id)
    {
        Apply(new AccountCreatedEvent { AggregateRootId = id });
    }
    public void handle(AccountCreatedEvent event) 
    {
        this.id = event.AggregateRootId
        this.status = "New"
    }
}

Apply()的实现通常只是在聚合它自己处理事件并缓存引发的事件。其他对象,通常是Repository负责获取缓存事件并发出它们。