繁体   English   中英

具有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
{
}

还是应将命令/请求视为DTO本身? 我很困惑,因为我看到了很多做事方法。 同样,将所有属性复制到命令/请求类听起来也不是一件好事。

您如何在项目中做到这一点?

您是将命令直接映射到域模型,还是仅使用命令来传递DTO?

在使用MVC框架的情况下,控制器操作的输入应该是什么? 应该是命令,还是应该在动作实现中创建命令并将其发送? (我想这将取决于我对命令的建模方式)

创建只保存对象的命令有意义吗?

不,额外的类没有任何价值:没有语义,没有行为...

还是应将命令/请求视为DTO本身?

命令(在术语CQRS的意义上)本质上是DTO。 它们是在层/层之间循环的笨拙的数据包。

您是否将命令直接映射到域模型

这取决于您是否偏爱基于任务的UI ,而不是基于CRUD的UI。 如果您执行DDD /富域模型-甚至有人说基本的OO封装-您将不会映射它们。 命令名称可能与实体方法匹配,但是它们的内容不会自动映射到域模型字段。

在使用MVC框架的情况下,控制器操作的输入应该是什么? 应该是命令,还是应该在动作实现中创建命令并将其发送?

我会说两者都是合法且适用的,除了偶尔带有MVC模型绑定的技术怪癖。

至少在我的世界中,命令和域对象具有不同的设计约束。 特别地,命令是API表面的一部分-它们是与其他服务的合同的一部分-因此,需要长期保持兼容的定义。 域对象,在另一方面,是地方我们当前的做事方式-他们是我们的黑匣子中的数据组织的一部分。 因此,我们可以按照自己喜欢的节奏来改变它们。

跨进程边界的命令是消息,即byte[]s 无论是形式还是语义,这都需要保持稳定。

byte[]是与域无关的,在“解析”消息时要经过其他几个与域无关的中间阶段是相当普遍的

byte[] -> utf8
utf8 -> DOM
DOM -> Dictionary
...

但我们通常会朝着特定领域的合同表达方向努力。

参见,例如Mark Seemann

在边界,应用程序不是面向对象的。 DTO是映射到面向对象语言的此类数据的表示。

已经裹挟着byte[]成一种形式,便于查询, 那么我们就可以开始考虑我们是否要使用这些数据来启动初始化“对象”。

您可能要问的另一个问题-将消息数据包含在通用元数据“信封”中是否有价值? 这种模式一直在发生-最常见的例子是HTTP POST是一堆附加到消息正文的通用标头。

数据和元数据当然是独立的关注点; 在解决方案中使其与众不同绝对是有意义的。

我认为合成数据结构,而不是继承它们,将是更可维护的选择。

public class Envelope<Message> ....

可能是一个合理的起点。

您应该将命令视为指示您的域执行某项操作的“语言句子”。 例如,“ UpdateCommand”指示您的域更新某些内容。 在命令内部,您应该包括命令的详细信息(如果您使用dto可以)...

但是,请谨慎使用那些DTO。 您不希望您的域依赖于MVC,反之亦然。 确保dto所在的程序集的级别(在MVC方向上)不高于域逻辑。

在您的MVC中,您应该只有:

  • 依赖注入设置
  • 控制器和视图

控制器应仅包含从方法(http)参数(巫婆不安全)转换为域所需的dto并调用域所需的代码。

至少那是我这样做的方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM