12

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

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

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

  • 用户模型参考 UserRepository,在 Validate() 中做唯一性检查
  • 使用 UserRepository 创建一个域服务来进行唯一性检查(这对我来说似乎有点奇怪,因为我认为通常只有在逻辑跨越多个域模型的情况下才使用域服务)
  • 在领域层创建一个规范对象,参考UserRepository封装唯一的检查规则,应用服务层用它来做更新/插入前的检查

如果我使用依赖注入,我仍然想知道如何将 UserRepository 注入方法 1 中的 User 或方法 2 中的域服务或方法 3 中的应用程序服务,因为无论如何,对于用户/域服务/规范对象,我需要手动实例化对象,所以我唯一的选择似乎是在 IoC 中使用服务定位器来获取实例。但是服务定位器是一种反模式,所以我想避免它

任何示例代码将不胜感激

4

1 回答 1

10

我认为检查唯一性属于存储库的责任。Repository 知道所有聚合,因为它假设模拟域集合,因此向 Repository 询问唯一性是很自然的(就像您对 HashMap 的期望一样)。

// 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);
}

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

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

有关替代方法,请参阅CQRS 架构中的唯一性验证。

于 2013-05-30T23:17:17.920 回答