我正在尽力使用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
实体类,该实体类包括一本Books的集合。
问题1:上面的命令具有Books
类型的Book
属性。我的问题是:Commands
项目是否应直接引用Model项目,以便在Book
中解析CreateNewBookShelfCommand
数据类型?我个人认为,不允许Contracts
引用除CommandHandlers
之外的任何项目,也不得引用任何其他可能是 Cross Cutting 的项目。
问题2:那么,这是在Book
项目中复制Contracts
实体类的一部分并在{{1} }?
这是我为CreateNewBookShelfCommand
和Book
设计的Model项目:
BookShelf
如果希望在此处添加其他信息,我希望我的解释已经足够。
答案 0 :(得分:2)
通常,您不会将域模型中的实体用作命令的元素。
命令从根本上讲是消息,因此它们确实应该是不变的。您想知道收到的与发送的相同。用DDD术语,您可能会认为消息是值对象。
使用域模型中的实体作为命令的内存表示形式的一部分没有任何意义,因为您永远不应调用任何更改其状态的实体方法。
从本质上讲,命令与数据传输对象的关系要比域模型实体的命令更紧密。
通常,系统中的所有实体对象都应位于聚合根接口之后,并且传递给该接口的参数为 values 。如果域模型需要一个实体,则可以从提供的值中创建一个。