根据 Fowler(此处)的说法,存储库“在域和数据映射层之间进行调解,就像内存中的域对象集合一样”。因此,例如,在我的 Courier Service 应用程序中,当提交新的运行时,我的应用程序服务会创建一个新的 Run 聚合根对象,使用请求中的值填充它,然后在调用工作单元保存之前将其添加到 RunRepository对数据库的更改。当用户想要查看当前运行的列表时,我会查询同一个存储库并返回一个表示信息的非规范化 DTO。
但是,在查看 CQRS 时,查询不会访问同一个存储库。相反,它可能会直接违背数据存储并且总是被非规范化。我的命令端将演变为 NewRunCommand 和 Handler,它们将创建和填充 NewRun 域对象,然后将信息保存到数据存储中。
所以第一个问题是,如果我们不维护域对象的内存中集合(缓存,如果你愿意的话),存储库在哪里适合 CQRS 模型?
考虑这样一种情况,提交给我的应用程序服务的信息只包含一系列 ID 值,服务必须解析这些 ID 值才能构建域对象。例如,请求包含分配给运行的快递员的 ID #。服务必须根据 ID 值查找实际的 Courier 对象,并使用 AssignCourier 方法(验证 courier 并执行其他业务逻辑)将该对象分配给 NewRun。
另一个问题是,考虑到查询的分离和存储库的潜在缺失,应用程序服务如何执行查找以找到 Courier 域对象?
更新
根据丹尼斯评论后的一些额外阅读和思考,我将重新表述我的问题。
在我看来,CQRS 鼓励存储库只是数据访问和数据存储机制的门面。它们给出了集合的“外观”(如 Fowler 所描述的),但不管理内存中的实体(如 Dennis 指出的那样)。这意味着存储库上的每个操作都是直通的,是吗?
工作单元如何适应这种方法?通常,UoW 用于提交对存储库所做的更改(对吗?)但是如果存储库没有维护内存中的实体,那么 UoW 有什么作用?
关于“写入”操作,命令处理程序是否会引用相同的存储库、不同的存储库或者可能是 UoW 而不是存储库?