【问题标题】:CQRS: Class Redundancy and passing DTO to DomainCQRS:类冗余并将 DTO 传递给域
【发布时间】:2017-09-12 06:48:27
【问题描述】:

我的 CQRS 应用程序有一些复杂的域对象。创建时,实体的所有属性都是由用户直接指定的,所以

CreateFooCommand 有大约 15 个属性。

FooCreatedEvent 因此也有 15 个属性,因为我需要读取端的所有实体属性。

由于命令参数必须分派给域对象,而 FooCreatedCommand 不应传递给域,

有一个从 CreateFooCommand 到域的手动映射。

由于域应该创建域事件,

这是从域 Foo 属性到 FooCreatedEvent 的另一个映射。

在读取方面,我使用 DTO 来表示 Foo 的结构,因为它存储在我的读取模型中。

因此更新读取端的事件处理程序引入了另一种从事件参数到 DTO 的映射。

为了实现一个简单的业务案例,我们有

  • 两个冗余类
  • 三个基本相同属性的映射

我想过摆脱命令/事件参数并推送 DTO 对象,但这意味着域可以接收或创建 DTO 并将其分配给事件。

顺序:

REST Controller --Command+DTO--> Command Handler --DTO--> Domain --(Event+DTO)--> Event Handler

关于减少 CQRS 实施痛苦的任何想法?

【问题讨论】:

    标签: c# domain-driven-design cqrs


    【解决方案1】:

    我看到以下选项:

    1. 通过在构造函数中注入它来创建一个不可变的 DTO 类 FooDetails,供 CreateFooCommand 和 FooCreatedEvent 使用;键入提示针对FooDetails 的聚合方法;例如new CreateFooCommand(new FooDetails(prop1, prop2, ...))

    2. 创建一个由CreateFooCommand 和FooCreatedEvent 继承的不可变基类FooDetails,并针对FooDetails 键入提示聚合方法

    3. 完全改变风格,使用cqrs.nu提倡的风格,直接向聚合发送命令;聚合具有命令方法,例如FooAggregate::handle(CreateFooCommand command);我个人经常使用这种风格。

    【讨论】:

      【解决方案2】:

      使用 CQRS + ES,您选择了一种包含更多移动部件的更复杂的方法,因为您知道它可以让您实现更多目标。忍受它。这种方法的优势在于分离关注点。 Command 是命令,Event 是事件,等等。尽管它们中的许多在链上可能看起来相似,但也可能存在例外。有些可能包含其他数据,或相同数据的略有不同的方面。命令可以具有与域无关的有关应用上下文的元信息(谁启动了命令、何时、是否重试等)。读取模型通常会包含有关要显示的相关对象的信息以及它们自己的信息(想想父子关系)。

      在阻止自己对这些异常进行建模之前,您可以删除的看似相似的代码只有这么多。并且在这些数据结构之间引入继承或组合通常比必须编写样板映射代码的原始痛苦更复杂。

      【讨论】:

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