c# - CQRS DDD - 命令和领域模型的关系
问题描述
我正在练习使用 CQRS 和 DDD 尽我所能来实施一个项目,并且在构建命令后提出了一个问题。
场景:用户发送命令在系统中创建一个书架,该书架本身也可以包含书籍集合。
该命令如下所示:
public class CreateNewBookShelfCommand : ICommand
{
public long CommandInitiatorId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ICollection<Book> Books { get; set; }
}
所有Commands
驻留在解决方案文件夹Contracts
内的项目中。Application
位于解决方案文件夹中的Model
项目Domain
托管BookShelf
实体类,其中包括书籍集合。
问题1: 上面的命令有这个Books
类型的属性Book
。我的问题是:Commands
项目是否应该直接引用 Model 项目,以便Book
在CreateNewBookShelfCommand
? 我自己,我不认为Contracts
允许引用除 theCommandHandlers
或任何其他可能是Cross Cut的项目之外的任何项目。
问题 2:那么,在项目中复制部分Book
实体类并在?Contracts
CreateNewBookShelfCommand
这是我的模型项目,Book
并且BookShelf
:
public class BookShelf : BaseEntity
{
public string Name { get; set; }
public string Description { get; set; }
public BookShelfAccess Access { get; set; }
public virtual BookShelfOwner Owner { get; set; }
public long OwnerId { get; set; }
public ICollection<Book> Books { get; set; }
}
public class Book : BaseEntity
{
public string Name { get; set; }
public DateTime? PublishedAt { get; set; }
public int NumberOfPublishes { get; set; }
public virtual BookShelf Shelf { get; set; }
public long ShelfId { get; set; }
}
我希望我的解释已经足够,如果我应该在这里添加任何其他信息让我知道。
解决方案
通常,您不会将域模型中的实体用作命令的元素。
命令本质上是消息,因此它们确实应该是不可变的。您想知道收到的内容与发送的内容相同。在 DDD 术语中,您可能将消息视为值对象。
使用域模型中的实体作为命令的内存表示的一部分是没有意义的,因为您永远不应该调用任何改变其状态的实体方法。
与域模型实体相比,命令在本质上更接近于数据传输对象。
通常,系统中的所有实体对象都应该存在于聚合根接口之后,并且传递给该接口的参数是values。如果域模型需要一个实体,它可以根据提供的值创建一个。
推荐阅读
- amazon-web-services - 使用 REST API 的 AWS S3 PUT 示例
- node.js - Mongoose 2dsphere 未创建,手动索引部分工作
- vba - 替换 MS-Word 中的文本框
- javascript - 事件监听器的范围
- javascript - 启动 chrome 崩溃 url 时出现“不允许加载本地资源”错误
- mysql - MySql - 如何使用 WHERE 子句从两个表中选择 MAX ID
- highcharts - Highcharts 热图不呈现正方形或矩形
- javascript - Vue 构建错误 @babel/compat-data 未找到
- python - jinja2.exceptions.UndefinedError - 列表对象没有元素 - 在 jinja2 模板中显示列表 - Flask
- mysql - 数字海洋sql连接和phpmyadmin突然停止工作