领域事件中涉及的实体可能还没有持久化呀?

13-08-21 2102x2
         

Domain event 乍看起来好像解决了一切问题, 用起来也很简单, 就像Udi Dahan什么的演示的那样。

但是现在有一个具体问题,不知道如何解决了:在ctor或者工厂方法中引发事件,由于涉及到的聚合当时还没有被持久化,handler中就没法访问相应的聚合了;甚至,如果是自动生成id的话,那时候id还不存在,连传递id也不行。

一些`hack`思路:

* 手动生成id

* (在app层)使用aop在事务结束的时候统一Dispatch所有在domain中收集到的事件

但是感觉比较猥琐,不知道各位大神有没有比较“权威”的做法?(No CQRS & EventSourcing)

class User
{
  private String id
  //xxoo....
  public Message postMessageToUser(String toWhom_id, String what)
  {
    def msg = new Message(toWhom_id, what)
    //Q: 在这里引发事件,但是此时msg还没有被持久化
    EventBus.instance.fire([msgId: msg.id, what: what, from:this.id] as MessagePostedEvent)
  }
}

//============================
class MessagePostedEventHandler
{
  @Inject private UserRepository userRepo
  @Inject private MessageRepository msgRepo

   //假定我们需要在handler里面获取相关聚合根的详细信息(只读)
  //Q:不管handler是同步还是异步,都不能保证相关的实体已经持久化了,就可能无法加载了
  public void handle(@Observes @Sync MessagePostedEvent e)
  {
    def sender = userRepo.load(e.from)
    def msg = msgRepo.load(e.id)
    println "user $sender posted a message: $msg"
  }
}
<p>

         

gameboyLV
2013-08-22 08:03

你使用的eventbus弱暴了,居然不支持先置条件。只要在fire时传入先置条件msg_initialized即可,满足先置条件后会自动触发已注册的事件。