Domain driven design 在聚合根/实体中注入存储库是否被视为糟糕的设计?

Domain driven design 在聚合根/实体中注入存储库是否被视为糟糕的设计?,domain-driven-design,Domain Driven Design,我正试图了解领域驱动设计的细节,我来到了这个问题。 我发现了许多例子: 在域内定义存储库接口 在其他地方定义存储库实现 将存储库接口注入聚合根目录 另一方面,也有一些例子严格违反了这一点,从服务中完成了所有与存储库相关的工作 我找不到权威的答案和解释:这被认为是一种不好的做法吗?如果是,为什么 我找不到权威的答案和解释:这被认为是一种不好的做法吗?如果是,为什么 是的,主要是因为许多不同的关注点被混淆了 聚合定义了一致性边界;状态的任何变化都应限于属于同一集合的相关实体的集合。因此,一旦您查找了

我正试图了解领域驱动设计的细节,我来到了这个问题。 我发现了许多例子:

  • 在域内定义存储库接口
  • 在其他地方定义存储库实现
  • 将存储库接口注入聚合根目录
  • 另一方面,也有一些例子严格违反了这一点,从服务中完成了所有与存储库相关的工作

    我找不到权威的答案和解释:这被认为是一种不好的做法吗?如果是,为什么

    我找不到权威的答案和解释:这被认为是一种不好的做法吗?如果是,为什么

    是的,主要是因为许多不同的关注点被混淆了

    聚合定义了一致性边界;状态的任何变化都应限于属于同一集合的相关实体的集合。因此,一旦您查找了第一个实体(“根”实体),就应该能够实现更改,而无需检查除此域实体图和已传递的参数之外的任何数据

    换句话说,
    存储库
    是一个管道问题,而不是域问题。您的域实体负责表示您的域,而不涉及基础架构问题

    例如,要有Aggregate.Save()方法,该方法将在内部使用IRepository接口进行保存

    Aggregate.Save()
    明确表示存在问题。准确地说,有两个问题:
    Save
    可能不是您普遍使用的语言的一部分,就这一点而言,
    Aggregate
    也可能不是

    Save
    不是域问题,而是持久性问题—它只是将数据从内存表示(易失性存储)复制到持久表示(稳定存储)。您的域模型不需要知道这方面的任何信息

    您发现“有很多示例”的原因之一是,要正确地分离这些关注点很难;这意味着你真的需要深入思考这个问题,把他们分开。大多数示例都没有,因为当您总是将所有内容部署在一起时,将它们分开并不重要

    我找不到权威的答案和解释:这被认为是一种不好的做法吗?如果是,为什么

    是的,主要是因为许多不同的关注点被混淆了

    聚合定义了一致性边界;状态的任何变化都应限于属于同一集合的相关实体的集合。因此,一旦您查找了第一个实体(“根”实体),就应该能够实现更改,而无需检查除此域实体图和已传递的参数之外的任何数据

    换句话说,
    存储库
    是一个管道问题,而不是域问题。您的域实体负责表示您的域,而不涉及基础架构问题

    例如,要有Aggregate.Save()方法,该方法将在内部使用IRepository接口进行保存

    Aggregate.Save()
    明确表示存在问题。准确地说,有两个问题:
    Save
    可能不是您普遍使用的语言的一部分,就这一点而言,
    Aggregate
    也可能不是

    Save
    不是域问题,而是持久性问题—它只是将数据从内存表示(易失性存储)复制到持久表示(稳定存储)。您的域模型不需要知道这方面的任何信息


    您发现“有很多示例”的原因之一是,要正确地分离这些关注点很难;这意味着你真的需要深入思考这个问题,把他们分开。大多数示例都不需要,因为当您总是将所有内容部署在一起时,将它们分开并不重要。

    为了更好地回答您的问题,我先退一步,想一想:为什么您需要聚合中的存储库?可能更适合于@GoloRoden,例如,
    aggregate.Save()
    方法,该方法将在内部使用
    IRepository
    界面进行保存。当然,另一种选择是使用一个生成聚合实例的服务,调用它需要的任何业务操作方法,然后调用
    IRepository.Save(aggregate aggregate instance)
    。(如果这回答了你的问题)我现在的回答与@VoiceOfUnreason在他们的回答中所写的内容类似。因此,我不会再添加其他答案,但我将+1它:-)谢谢您的评论!如果您想在@VoiceOfUnreasons答案中添加任何内容,请将其放在另一个答案中,我将对此进行投票。为了更好地回答您的问题,我先退一步,想一想:为什么您需要在聚合中使用存储库?可能更适合于@GoloRoden,例如,
    aggregate.Save()
    方法,该方法将在内部使用
    IRepository
    界面进行保存。当然,另一种选择是使用一个生成聚合实例的服务,调用它需要的任何业务操作方法,然后调用
    IRepository.Save(aggregate aggregate instance)
    。(如果这回答了你的问题)我现在的回答与@VoiceOfUnreason在他们的回答中所写的内容类似。因此,我不会再添加其他答案,但我将+1它:-)谢谢您的评论!如果您想在@VoiceOfUnreasons答案中添加任何内容,请将其放在另一个答案中,我将投票支持。“保存可能不是您普遍使用的语言的一部分”-谢谢您的这句话!这是完全有道理的,是的,我确实忽略了od DDD这一方面。我关注的是saving实现的位置,以及它的外部域(和注入域)似乎可以接受的事实。但是哈文