与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))
}
}
业务逻辑有一些复杂性,但我真的很感兴趣,只有在持久保存域对象后才能触发事件。
编辑:如果电子邮件发送失败并不是那么重要,如果状态没有“采取”,则不会发送电子邮件,因为组织中的高级人员可能会收到邮箱中的无效说明。
答案 0 :(得分:1)
拥有一致的事务行为会更好。您可以在同一事务(队列或数据库)中提交事件,并从那里调度。无论如何,如果这不是您正在寻找的,您也可以将您的聚合记录事件而不是直接提升它。这允许您首先提交数据库事务,然后分派事件。
public interface IRecordingAggRoot {
IEnumerable<IEvent> RecordEvents();
}
_repository.Save(aggregate);
_tx.Commit();
_dispatcher.Dispatch(aggregate.RecordedEvents());