【问题标题】:Should I add item using repository pattern or a create event if I am using domain events?如果我使用域事件,我应该使用存储库模式添加项目还是创建事件?
【发布时间】:2012-08-27 23:06:55
【问题描述】:

我正在尝试了解Domain Event pattern illustrated by Udi Dahan 在特定情况下添加新域实体。

现在通常我会创建实体,然后通过存储库添加它们。我想我还会这样做吗?

我的例子是我们通常将资产添加到系统中。像这样:

 var asset= new Asset();
/*bunch of prop setting*/
 _assetRepository.Add(asset);

但是,资产创建是我们希望遵循某些流程的结果。因此,开发人员建议我们不再需要这样做,因为它可以由域事件处理:

var asset= new Asset();
   /*bunch of prop setting*/
asset.Create(location);

现在 create 方法会引发一个事件并由一个 create 事件处理程序处理,该处理程序基本上只是将它插入到 repo 中,并做一些其他的事情给创建位置的仓库经理等发送电子邮件。

但是,在资产上创建事件对我来说看起来很活跃。然而,在领域中,人们谈论正在创建的新资产。所以我们不确定。

想法?

【问题讨论】:

    标签: domain-driven-design repository-pattern ddd-repositories domain-events


    【解决方案1】:

    创建的域事件应该在Asset 类的构造函数中引发,因为那是创建特定实体的时间。在您当前的实现中,这将是错误的,因为 Asset 实体提供了一个无参数的构造函数。相反,创建一个具有所有必需属性作为参数的构造函数,从而防止创建处于不一致状态的资产实体。它可能看起来像这样:

    public class Asset
    {
      public Asset(string prop1, decimal prop2) 
      {
        this.Prop1 = prop1;
        this.Prop2 = prop2;
        DomainEvents.Raise(new AssetCreated(prop1, prop2));
      }
    
      public string Id { get; private set; }
      public string Prop1 { get; private set; }
      public decimal Prop2 { get; private set; }
    }
    

    在创建实体后,您仍然必须使用存储库来持久化实体。这可能会产生问题,因为AssetCreated 的处理程序无法引用其 ID,因为在收到通知时尚未分配它。如果使用事件溯源,则创建事件将显式存储在底层事件存储中。

    【讨论】:

    • 好吧,我明白这是有道理的。但是,正如您所说,我的问题是不知道作为身份的 AssetId(没有自然键),当引发 create 事件时,我将无法访问它。因此,我如何在提出的电子邮件等中引用资产。我想我必须想办法将它重新组合在一起。
    • 一种方法是为 AssetId 使用 Guid。要注意的另一件事是,无论您对该事件做什么都必须是事务性的,因为如果由于某种原因创建或更新的实体没有被持久化,则域事件的处理程序所采取的所有操作都不再有效。
    • 我在考虑指导。是的,可能需要将东西添加到队列中,然后如果事务失败/未完成则将它们拉出
    【解决方案2】:

    我已经为这个问题苦苦挣扎了很长时间。但没有好的解决办法。我想,

    • 在成功持久化它所属的聚合之前,不应发布或处理域事件
    • 应用层不负责发布任何事件

    到目前为止,我认为最好的方法是利用 AOP。我们可以在聚合中“触发”事件,但不是立即分派它们,而是将其保存在队列中,并在相应的事务成功后真正分派它。
    我们可以定义一个自定义的@Transactional 拦截器来实现这一点,从而使应用服务不知道任何“事件发布”的概念。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-05
      相关资源
      最近更新 更多