我是否应该将存储库传递给引发事件的域方法 [英] Should I Pass a repository to a Domain Method that fires an Event

查看:36
本文介绍了我是否应该将存储库传递给引发事件的域方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题:我应该将存储库传递给需要在方法动作发生并保持后触发事件的域对象方法吗?

slightly related to this question: Should I pass a repository to a domain object method that needs to fire an event after the methods actions have occurred and been persisted?

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

In this case the system needs to send emails of after the domain object's status is changed. Whilst unlikely, it could happen that the status change would not be persisted in which case the email should not be sent.

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

I could use a domain service to do the work, but all the logic of status changing belongs and is contained in the domain object so my services would end up looking like

 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(其中一种是现在有两种更改状态的方法,只有一种可以发送电子邮件)

Which id rather not do for several reason (one of which is there are now 2 ways of changing status only one of which sends the emails)

Id喜欢将其包装在Domain Method本身中,但这也感觉不对,因为我要让Domain对象负责其自身的持久性。 (尽管我认为我更喜欢使用域服务方式)

Id like to wrap it up in the Domain Method itself but this also doesn't feel right because I'm making the domain object responsible for its own persistence. (although I think I prefer it over the domain service way)

 class DomainObject() : IAggRoot {

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

 }

业务逻辑有些复杂,但实际上我只对域对象持久化后的事件感兴趣。

There's a bit of complications about the business logic, but really I'm interested how to fire events ONLY after the Domain Objects are persisted.

编辑:如果电子邮件无法发送,则不是很重要;如果状态不采用,则不要发送电子邮件,这很重要,因为组织中的高级人员可能会在其邮箱中收到无效的指令。

It is not so important if the email fails to send, it is important that an email is not sent if the status does not 'take' as senior people in the organisation people may receive invalid instructions in their mailbox..

推荐答案

拥有一致的交易行为会更好。您可以在同一事务(队列或数据库)中提交事件,然后从那里调度。无论如何,如果这不是您想要的内容,那么您也可以让聚合记录该事件,而不是直接引发该事件。这样,您就可以首先提交数据库事务,然后调度事件。

It would be nicer to have consistent transactional behavior. You could commit events in the same transaction (queue or db), and dispatch from there. Anyways, if this is not what you're looking for, you could also have your aggregate record the event instead of having it raise it directly. This allows you to first commit your database transaction, and then to dispatch the event.

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

_repository.Save(aggregate);
_tx.Commit();
_dispatcher.Dispatch(aggregate.RecordedEvents());

这篇关于我是否应该将存储库传递给引发事件的域方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆