我应该将存储库传递给触发事件的域方法

时间:2014-02-28 01:58:49

标签: domain-driven-design ddd-repositories

this question略有关联:我是否应该将存储库传递给域对象方法,该方法需要在方法操作发生并且持久化之后触发事件?

在这种情况下,系统需要在域对象的状态更改后发送电子邮件。虽然不太可能,但可能会发生状态变化不会持续存在,在这种情况下不应发送电子邮件。

我可以使用域服务来完成工作,但状态更改的所有逻辑都属于并包含在域对象中,所以我的服务最终会看起来像

 StatusService(Irepo repo) {

        void ChangeStatus(domainObject myObject, status newStatus) {
              try {
              myObject.ChangeStatus(newStatus);
              repo.Save(myObject);
              raiseEvent(new StausChangeEmailEvent(myObject))
              } catch { .. dont send email }
         }

由于多种原因(其中一个是现在有两种更改状态的方式,其中只有一种发送电子邮件),而不是这样做的id

我想将它包装在Domain Method本身中,但这也感觉不对,因为我让域对象负责自己的持久性。 (虽然我认为我更喜欢域名服务方式)

 class DomainObject() : IAggRoot {

 ...
 public ChangeStatus(irepo repo, status newStatus) {
    ..logic logic 
    this.Status = newStatus;
    repo.Save(this);
    raiseEvent(new StausChangeEmailEvent(myObject))
 }

 }

业务逻辑有一些复杂性,但我真的很感兴趣,只有在持久保存域对象后才能触发事件。

编辑:如果电子邮件发送失败并不是那么重要,如果状态没有“采取”,则不会发送电子邮件,因为组织中的高级人员可能会收到邮箱中的无效说明。

1 个答案:

答案 0 :(得分:1)

拥有一致的事务行为会更好。您可以在同一事务(队列或数据库)中提交事件,并从那里调度。无论如何,如果这不是您正在寻找的,您也可以将您的聚合记录事件而不是直接提升它。这允许您首先提交数据库事务,然后分派事件。

public interface IRecordingAggRoot {
     IEnumerable<IEvent> RecordEvents();
}

_repository.Save(aggregate);
_tx.Commit();
_dispatcher.Dispatch(aggregate.RecordedEvents());
相关问题