DDD 存储库对其他存储库的认知

发布于 2024-08-02 22:55:54 字数 465 浏览 9 评论 0原文

一个存储库可以访问另一个存储库通常可以接受吗?具体来说,在这种情况下,我有一个聚合根,它使用另一个聚合根来确定要添加哪些实体。它遵循项目/项目类型关系。项目类型是聚合根的原因是它们可以在任何单个项目范围之外的管理工具中单独维护。

如果确实重要的话,我只是通过存储库工厂实现来创建存储库实例,因此我不会直接通过具体类名来创建它。聚合体在任何时候都不会意识到存储库。

编辑-更多信息:

具体实现是我们可以将图像附加到文档中。我们不仅可以管理文档上的图像,而且还存在不同类型的图像(例如,类型被定义为其实现方式,而不是扩展)。文档聚合是系统中使用这些图像的几种其他对象类型之一,并且它们并不都使用相同的类型。虽然我们确实在域服务中附加了规则,但这更具体地用于构建文档聚合。在构建聚合时,我们有五张特定类型的图像,以及其他两种类型各一张。我们单独提取它们,因为它们存储在聚合中的单独列表中。验证不是问题,但限制了在组装文档时评估的图像类型。

Is it generally acceptable that one repository can access another repository? Specifically in this case, I have one aggregate root that uses another aggregate root to determine what entities to add. It falls along the lines of an Item/Item Type relationship. The reason that the Item Type is an aggregate root is that they are separately maintainable within a management tool outside of the scope of any single Item.

If it does matter, I am only creating my repository instances through a repository factory implementation, so I am not directly creating it by the concrete class name. At no time is the aggregate aware of the repository.

Edit - More information:

The specific implementation is that we can attach images to a document. Not only can we manage the images on the document, but there are different types of images (types being defined as how it is implemented, as opposed to an extension, for example). The document aggregate is one of a few types of other objects in the system that use these images and they do not all use the same types. While we do attach rules in the domain services, this is more specifically geared towards building the document aggregate. When building the aggregate we have five images of a specific type, and one each of two other types. We pull these individually because they are stored in separate lists in the aggregate. The validation is not the issue, but limiting what type of images are being evaluated when assembling the document.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苏佲洛 2024-08-09 22:55:54

我想这可以归结为你想要做什么。如果这是一种验证步骤(例如,删除具有已过期项目类型的所有项目),您可能会认为它属于服务层或规范。从您使用的语言(即“确定要添加哪些实体”)来看,它似乎建议后者,尽管没有更多细节很难说。

我想从某个角度来看,没有真正的理由不能(我绝不是最纯粹的超级 DDD),特别是因为 Item 及其类型可以被视为聚合根,而它只是实现细节您需要提供一个可以防止的管理控制台。

从另一个角度来看,这似乎确实表明您的聚合根源之间存在模糊,这可能表明两种不同的背景正在发挥作用。例如,有人可能会争辩说,管理工具形成了与主应用程序不同的有界上下文,因此 Item 类型作为聚合根的情况并不真正适用。例如,管理工具可能只关心项目类型(而不是项目),而您的主应用程序可能将项目类型更多地视为值对象而不是实体。

更新

正如您提到的组装文档,这似乎是可以正确组装有效实体的工厂类的责任(工厂可以使用图像类型存储库)。存储库应该(在我看来)公开查询和添加操作,而不是配置实体的逻辑(除了可能从持久性中重新水化)。

I guess it boils down to what your trying to do. If it's a sort of validation step (e.g. remove all items that have item types that have expired) you could argue it belongs in a service layer or specification. From the language you use (i.e. "determine what entities to add") it seems to suggest the latter, though it's hard to say without more details.

I guess from a certain point of view there's no real reason why you can't (I'm by no means a super DDD purest), especially since an Item and its type could be viewed as an aggregate root and it's only the implementation detail that you need to provide a management console that's prevent.

From another point of view it does seem to suggest that there's a blurring between your aggregate roots that could suggest two different contexts are at work. For instance, one could argue that a management tool forms a separate bounded context to your main application and therefore the case for the Item type being an aggregate root does not really apply. e.g. The management tool might only ever be concerned with Item Types (and never items) while your main application might view item types as more of a value object than an entity.

Update

As you mention assembling the document this seems like the responsibility of a factory class that can correctly assemble a valid entity (the factory can use the image type repository). A repository should (in my eyes) expose querying and adding operations, not the logic to configure entities (except maybe rehydrating from persistence).

我不在是我 2024-08-09 22:55:54

让一个存储库使用另一个存储库并不遵循 DDD 原则。如果您需要来自一个聚合根的数据来对另一个聚合根执行某些操作,您可以检索第一个根(在应用程序服务层或可能在域服务中),然后将该数据传递到依赖聚合根的公共 api ,或者在使用单独工厂的聚合根创建的情况下,进入工厂的公共 api。

聚合根定义了事务边界,其中的数据应保持事务一致性。这种对事务一致性的期望不应扩展到该边界之外的任何事物。如果您有一个依赖于另一个存储库的存储库,那么您的一个聚合的状态在事务上依赖于另一个聚合的状态,这意味着这些“聚合根”实际上都不是聚合根。

此外,如果您需要更改一个聚合的状态以影响另一个聚合的状态,则应为此使用域事件,这会强制根之间的最终一致性

It does not follow the principles of DDD to have one repository using another repository. If you need data from one aggregate root to perform some action on another aggregate root, you can retrieve the first root (in the application service layer or possibly in a domain service) and then pass that data into the public api of the dependent aggregate root, or in the case of aggregate root creation where a separate factory is being used, into the factory's public api.

An aggregate root defines a transactional boundary, where the data within it should remain transactionally consistent. This expectation of transactional consistency should not extend to anything outside that boundary. If you have a repository dependent on another respository then you have the state of one aggregate being transactionally dependent on the state another aggregate, which means neither of these 'aggregate roots' are actually aggregate roots.

Furthermore, if you need changes to state of one aggregate to effect the state of another aggregate, you should use domain events for this, which enforce eventual consistency between the roots.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文