Domain driven design 存储库如何适应CQR?
根据Fowler(),存储库“在域和数据映射层之间进行调解,就像内存中的域对象集合一样。”因此,例如,在我的Courier Service应用程序中,当提交新运行时,我的应用程序服务将创建一个新的运行聚合根对象,使用请求中的值填充它,然后在调用工作单元将更改保存到数据库之前将其添加到RunRepository。当用户想要查看当前运行的列表时,我查询同一存储库并返回一个表示信息的非规范化DTO 但是,当查看CQR时,查询不会命中同一存储库。相反,它可能会直接违反数据存储,并且总是被非规范化。我的命令端将演变为NewRunCommand和处理程序,它将创建并填充一个NewRun域对象,然后将信息持久化到数据存储中 因此,第一个问题是,如果我们不维护域对象的内存中集合(缓存,如果您愿意),那么存储库在CQRS模型中的位置如何 考虑这样一种情况,提交给我的应用程序服务的信息只包含一系列ID值,服务必须解析这些ID值才能构建域对象。例如,请求包含分配给跑步的快递员的ID。服务必须根据ID值查找实际的Courier对象,并使用AssignCourier方法(验证Courier并执行其他业务逻辑)将该对象分配给NewRun 另一个问题是,考虑到查询分离和可能缺少存储库,应用程序服务如何执行查找以查找Courier域对象 更新 根据丹尼斯评论后的一些额外阅读和思考,我将重新表述我的问题 在我看来,CQR鼓励存储库仅仅是数据访问和数据存储机制的外表。它们提供集合的“外观”(如Fowler所描述的),但不管理内存中的实体(正如Dennis所指出的)。这意味着存储库上的每个操作都是通过的,是吗 工作单元如何适应这种方法?通常,UoW用于提交对存储库所做的更改(对吗?),但是如果存储库没有在内存中维护实体,那么UoW的角色是什么Domain driven design 存储库如何适应CQR?,domain-driven-design,cqrs,ddd-repositories,Domain Driven Design,Cqrs,Ddd Repositories,根据Fowler(),存储库“在域和数据映射层之间进行调解,就像内存中的域对象集合一样。”因此,例如,在我的Courier Service应用程序中,当提交新运行时,我的应用程序服务将创建一个新的运行聚合根对象,使用请求中的值填充它,然后在调用工作单元将更改保存到数据库之前将其添加到RunRepository。当用户想要查看当前运行的列表时,我查询同一存储库并返回一个表示信息的非规范化DTO 但是,当查看CQR时,查询不会命中同一存储库。相反,它可能会直接违反数据存储,并且总是被非规范化。我的命
关于“写入”操作,命令处理程序是否会引用同一个存储库、不同的存储库或UoW而不是存储库?我已经了解了CQRS系统,这些系统在命令端维护一个简单的键值存储来表示应用程序的状态,以及其他仅关联消息的系统(使用某种saga)并使用查询存储来表示应用程序状态。无论采用哪种方法,这些方法都无疑涉及到持久化技术,但在这些情况下,存储库模式将是一种不必要的抽象 不过,我在CQR方面的经验仅限于事件源,我们重播了过去的事件,以重建封装和强制执行业务逻辑和不变量的聚合。在这种情况下,存储库模式是一种熟悉的抽象,可以提供一种更简单的方法来检索这些聚合 关于查询方面,我建议尽可能靠近数据存储,我的意思是避免在UI(不管是什么)和数据存储之间出现任何存储库、服务或外观等 看看这些方法在使用中的例子可能会有所帮助。也许可以看看以下项目:
Assert.IsFalse(newEvent.Items.Any())
IOrderEvent newEvent = eventFactory.CreateOrderItemEvent(myItemID);
currentOrder = orderRepository.ApplyEvents(currentOrder, newEvent);
Assert.IsTrue(newEvent.Items.Any())
我现在应该看到currentOrder。项目有一个条目
这里的缺点是,我的所有处理都是通过事件完成的,而不是将我的业务逻辑放在实体中在多个系统上工作,这实际上效果很好。Fowler在中的定义与Eric Evan在DDD boo中描述的存储库模式略有不同