【发布时间】:2014-08-29 16:19:34
【问题描述】:
我很难找出实现依赖于数据库中存储的数据的业务规则验证的最佳方法。在下面的简化示例中,我想确保 Username 属性是唯一的。
public class User() {
public int Id { get; set; }
public string Name { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string GenerateRandomPassword() {
}
}
public interface IUserRepository : IRepository<User>
{
bool UsernameTaken(string username);
}
public interface IUnitOfWork : IDisposable
{
void Commit();
IUserRepository Users { get; }
}
我已经阅读了很多关于实现该目标的不同方法的资料,包括将存储库注入实体(并防止它进入无效状态)、创建扩展方法等。
但我认为这些都不是最好的方法。
所以我决定使用应用程序服务来编排使用规范的实体验证。
public class CreateUserService : ICreateUserService
{
private readonly IUnitOfWork _uow;
public CreateUserService(IUnitOfWork uow)
{
_uow = uow;
}
public User Create(User user)
{
var usernameAvailableSpecification = new UsernameAvailableSpecification(_uow.Users);
if (!usernameAvailableSpecification.IsSatisfiedBy(user))
{
throw new ValidationException("Username already taken");
}
user.GenerateRandomPassword();
_uow.Users.Store(user);
_uow.Commit();
return user;
}
}
起初,它看起来不错。但是单元测试有点困难,因为服务与规范实现紧密耦合,并且必须手动处理规范的依赖关系。我也想过抽象规范,但我不确定我是否是正确的路径。
也有可能我开始错了,因为实际上我正在学习 DDD,但我仍然不清楚应该由哪一层来负责这种验证。
任何帮助将不胜感激。
【问题讨论】:
标签: validation domain-driven-design ddd-repositories ddd-service