具有 MediatR 的 CQRS 和命令的可重用性
CQRS with MediatR and re-usability of commands
创建仅包含对象的命令是否有意义?例如:
public class CreateCommand : IRequest
{
SomeDTO SomeDTO { get; set; }
}
public class UpdateCommand : IRequest
{
SomeDTO SomeDTO { get; set; }
}
或者可能是这样的(推导):
public class UpdateCommand : SomeDTO, IRequest
{
}
或者 commands/requests 本身应该被视为 DTO?我很困惑,因为我看到了很多做事的方法。将所有属性复制到 command/request 类 听起来也不是一件好事。
你是如何在你的项目中做到这一点的?
您是将命令直接映射到域模型,还是仅使用命令来传递 DTO?
如果使用 MVC 框架,我的控制器操作的输入应该是什么?它应该是一个命令,还是应该在我的操作实现中创建命令并发送它? (我想这将取决于我如何建模我的命令)
您应该将此命令视为 "verbal sentence" 指示您的域执行某些操作。例如 "UpdateCommand" 指示您的域更新某些内容。在命令中你应该包括命令的细节(在你的情况下 dto 很好)...
但是要非常小心那些 DTO。您不希望您的域依赖于 MVC,但相反。确保 dto 所在的程序集不属于比域逻辑更高的级别(在 MVC 的方向上)。
在您的 MVC 中,您应该只有:
- 依赖注入设置
- 控制器和视图
控制器应仅包含从方法 (http) 参数( 不安全)转换为域所需的 dto 并调用域所需的代码。
至少我是这样做的。
命令和域objects,至少在我的世界里,有不同的设计约束。特别是,命令是 API 表面的一部分——它们是与其他服务的契约的一部分——因此需要在很长一段时间内具有兼容的定义。另一方面,域 objects 是我们当前做事方式的局部 - 它们是我们在 黑匣子内组织数据的一部分。所以我们可以按照我们喜欢的任何节奏更改它们。
跨越进程边界的命令是消息,也就是说byte[]s
。这就是需要在形式和语义上保持稳定的位。
byte[]
与域无关,并且在 "parsing" 消息
中通过其他几个与域无关的中间阶段是相当普遍的
byte[] -> utf8
utf8 -> DOM
DOM -> Dictionary
...
但我们通常会朝着 特定领域 合同表达的方向发展。
见,例如Mark Seemann
At the boundaries, applications are not object-oriented.
A DTO is a representation of such a piece of data mapped into an object-oriented language.
将byte[]
强制转换成方便查询的形式,然后我们可以开始考虑要不要用那个数据开始初始化"objects".
您可能会问的另一个问题 - 在通用元数据中包含消息数据是否有价值 "envelope"。这种模式一直存在——最熟悉的例子是 HTTP POST 是一堆通用的 headers 附加到 message-body.
数据和元数据当然是不同的问题;在您的解决方案中让它们与众不同绝对有意义。
我认为组合数据结构而不是继承它们将是更易于维护的选择。
public class Envelope<Message> ....
可能是一个合理的起点。
Does it make sense to create commands that just hold objects?
不,没有附加值class:没有语义,没有行为...
Or commands/requests should be treated as DTOs themselves?
命令(在术语 中)本质上是 DTO。它们是在 layers/tiers.
之间循环的哑数据包
Do you map your commands directly to your domain models
这取决于您是否喜欢 task-based UI 而不是基于 CRUD 的 UI。如果你做 DDD/rich 领域模型——有些人甚至会说基本的 OO 封装——你就不会映射它们。命令名称可能匹配实体 方法 ,但它们的内容不会自动映射到域模型字段。
In case of using MVC framework what should be the input of my
controller actions? Should it be a command, or should I create command
inside my action implementation and send it?
我会说两者都是合法且适用的,除了 MVC 模型绑定偶尔出现的技术怪癖。
创建仅包含对象的命令是否有意义?例如:
public class CreateCommand : IRequest
{
SomeDTO SomeDTO { get; set; }
}
public class UpdateCommand : IRequest
{
SomeDTO SomeDTO { get; set; }
}
或者可能是这样的(推导):
public class UpdateCommand : SomeDTO, IRequest
{
}
或者 commands/requests 本身应该被视为 DTO?我很困惑,因为我看到了很多做事的方法。将所有属性复制到 command/request 类 听起来也不是一件好事。
你是如何在你的项目中做到这一点的?
您是将命令直接映射到域模型,还是仅使用命令来传递 DTO?
如果使用 MVC 框架,我的控制器操作的输入应该是什么?它应该是一个命令,还是应该在我的操作实现中创建命令并发送它? (我想这将取决于我如何建模我的命令)
您应该将此命令视为 "verbal sentence" 指示您的域执行某些操作。例如 "UpdateCommand" 指示您的域更新某些内容。在命令中你应该包括命令的细节(在你的情况下 dto 很好)...
但是要非常小心那些 DTO。您不希望您的域依赖于 MVC,但相反。确保 dto 所在的程序集不属于比域逻辑更高的级别(在 MVC 的方向上)。
在您的 MVC 中,您应该只有:
- 依赖注入设置
- 控制器和视图
控制器应仅包含从方法 (http) 参数( 不安全)转换为域所需的 dto 并调用域所需的代码。
至少我是这样做的。
命令和域objects,至少在我的世界里,有不同的设计约束。特别是,命令是 API 表面的一部分——它们是与其他服务的契约的一部分——因此需要在很长一段时间内具有兼容的定义。另一方面,域 objects 是我们当前做事方式的局部 - 它们是我们在 黑匣子内组织数据的一部分。所以我们可以按照我们喜欢的任何节奏更改它们。
跨越进程边界的命令是消息,也就是说byte[]s
。这就是需要在形式和语义上保持稳定的位。
byte[]
与域无关,并且在 "parsing" 消息
byte[] -> utf8
utf8 -> DOM
DOM -> Dictionary
...
但我们通常会朝着 特定领域 合同表达的方向发展。
见,例如Mark Seemann
At the boundaries, applications are not object-oriented. A DTO is a representation of such a piece of data mapped into an object-oriented language.
将byte[]
强制转换成方便查询的形式,然后我们可以开始考虑要不要用那个数据开始初始化"objects".
您可能会问的另一个问题 - 在通用元数据中包含消息数据是否有价值 "envelope"。这种模式一直存在——最熟悉的例子是 HTTP POST 是一堆通用的 headers 附加到 message-body.
数据和元数据当然是不同的问题;在您的解决方案中让它们与众不同绝对有意义。
我认为组合数据结构而不是继承它们将是更易于维护的选择。
public class Envelope<Message> ....
可能是一个合理的起点。
Does it make sense to create commands that just hold objects?
不,没有附加值class:没有语义,没有行为...
Or commands/requests should be treated as DTOs themselves?
命令(在术语
Do you map your commands directly to your domain models
这取决于您是否喜欢 task-based UI 而不是基于 CRUD 的 UI。如果你做 DDD/rich 领域模型——有些人甚至会说基本的 OO 封装——你就不会映射它们。命令名称可能匹配实体 方法 ,但它们的内容不会自动映射到域模型字段。
In case of using MVC framework what should be the input of my controller actions? Should it be a command, or should I create command inside my action implementation and send it?
我会说两者都是合法且适用的,除了 MVC 模型绑定偶尔出现的技术怪癖。