Dependency injection DDD中的唯一性验证

Dependency injection DDD中的唯一性验证,dependency-injection,repository,domain-driven-design,unique,specifications,Dependency Injection,Repository,Domain Driven Design,Unique,Specifications,我有一个关于检查DDD中唯一性的问题。我知道已经有一些关于stackoverflow的问题了,但是他们并没有真正回答我的疑问 在更新/插入数据库时,聚合根目录是否可以保存存储库的引用以检查唯一性?或者这是由应用程序服务而不是域模型完成的任务 假设我想在用户注册时检查用户模型的用户名是否唯一 我可以想到几种方法: 用户模型引用UserRepository,在Validate()中执行唯一性检查 使用UserRepository创建一个域服务来进行唯一性检查(这对我来说似乎有点奇怪,因为我认为通常

我有一个关于检查DDD中唯一性的问题。我知道已经有一些关于stackoverflow的问题了,但是他们并没有真正回答我的疑问

在更新/插入数据库时,聚合根目录是否可以保存存储库的引用以检查唯一性?或者这是由应用程序服务而不是域模型完成的任务

假设我想在用户注册时检查用户模型的用户名是否唯一 我可以想到几种方法:

  • 用户模型引用UserRepository,在Validate()中执行唯一性检查
  • 使用UserRepository创建一个域服务来进行唯一性检查(这对我来说似乎有点奇怪,因为我认为通常只有在逻辑跨越多个域模型的情况下才使用域服务)
  • 在域层中创建一个规范对象,引用UserRepository来封装唯一的检查规则,应用程序服务层使用它在更新/插入之前进行检查
如果我使用依赖注入,我仍然想知道如何将UserRepository注入方法1中的用户,或方法2中的域服务,或方法3中的应用程序服务,因为在任何情况下,对于用户/域服务/规范对象,我需要手动实例化对象,所以我唯一的选择似乎是在IoC中使用服务定位器来获取实例。但是服务定位器是一种反模式,所以我想避免它


任何示例代码都将非常受欢迎

我认为检查唯一性属于存储库的责任。存储库知道所有聚合,因为它假设模拟域集合,所以要求存储库提供唯一性是很自然的(就像您从HashMap中期望的那样)

从某种意义上说,这是一个泄漏的抽象,因为在多用户环境中,这需要在数据存储端强制执行(例如,唯一SQL约束或锁定)

IsNameUnique可能不应从用户聚合中调用,我会将此调用移动到应用程序或域服务中,具体取决于应用程序其余部分的结构


有关替代方法,请参阅。

我认为您应该在服务层中实现这一点。更具体地说,为特定类型的业务逻辑(您的命令)定义一个验证器类,并在围绕服务类的decorator中处理验证。这会有帮助吗@Steven那么我应该创建一个UserValidator来实现服务层中的用户检查?是否认为业务规则(用户名的唯一性)泄漏到域层之外?因此,您建议遵循上面的方法2,创建一个域服务来调用存储库以检查唯一性?在DDD中,像这样在域层创建验证服务是常见的方法吗?我是DDD新手,所以不太确定是从域还是从应用程序服务使用此存储库取决于您的用例,只要您不从聚合中使用此方法,任何一种都可以。谢谢,最后我决定采用这种方法:
// repository
interface Users {
  // implementation executes SQL COUNT in case of relation DB
  bool IsNameUnique(String name);

  // implementation will call IsNameUnique and throw if it fails
  void Add(User user);
}