DDD中的唯一验证

时间:2013-05-30 04:01:59

标签: dependency-injection repository domain-driven-design unique specifications

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

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

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

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

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

非常感谢任何示例代码

1 个答案:

答案 0 :(得分:5)

我认为检查唯一性属于存储库责任。存储库知道所有聚合,因为它假设模拟域集合,因此很自然地要求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,我会将此调用移动到应用程序或域服务中,具体取决于应用程序的其余部分的结构。

有关替代方法,请参阅Uniqueness validation in CQRS Architecture