在 DDD 中放置全局规则验证的位置
我是DDD的新手,我正在尝试将其应用于现实生活中。对于这样的验证逻辑,如空检查,空字符串检查等,没有问题 - 直接进入实体构造函数/属性。但是,在哪里可以验证一些全局规则,例如“唯一用户名”?
所以,我们有实体用户
public class User : IAggregateRoot
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
// other data and behavior
}
和用户存储库
public interface IUserRepository : IRepository<User>
{
User FindByName(string name);
}
选项包括:
- 将存储库注入实体
- 将存储库注入工厂
- 在域服务上创建操作
- ???
每个选项更详细:
1 .将存储库注入实体
我可以在实体构造函数/属性中查询存储库。但我认为在实体中保留对存储库的引用是一种难闻的气味。
public User(IUserRepository repository)
{
_repository = repository;
}
public string Name
{
get { return _name; }
set
{
if (_repository.FindByName(value) != null)
throw new UserAlreadyExistsException();
_name = value;
}
}
更新:我们可以使用DI通过规范对象隐藏用户和IUser存储库之间的依赖关系。
2. 将存储库注入工厂
我可以把这个验证逻辑放在UserFactory中。但是,如果我们想更改现有用户的名称怎么办?
3. 在域服务上创建操作
我可以创建用于创建和编辑用户的域服务。但是有人可以直接编辑用户的名称,而无需调用该服务...
public class AdministrationService
{
private IUserRepository _userRepository;
public AdministrationService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public void RenameUser(string oldName, string newName)
{
if (_userRepository.FindByName(newName) != null)
throw new UserAlreadyExistException();
User user = _userRepository.FindByName(oldName);
user.Name = newName;
_userRepository.Save(user);
}
}
4. ???
将实体的全局验证逻辑放在哪里?
谢谢!