c# – DDD域模型复杂验证

前端之家收集整理的这篇文章主要介绍了c# – DDD域模型复杂验证前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用域驱动的设计版本来重写我的ASP.NET MVC应用程序.我试图验证我的用户实体.到目前为止,我可以验证基本规则(如用户名和密码是非空/空白字符串).然而,其中一个规则,我需要确保用户名是唯一的.然而,我需要访问数据库才能做到这一点,这意味着我必须将我的IUserRepository注入我的用户实体.
public class User
{
    private readonly IUserRepository _userRepository;
    public User(IUserRepository repo)
    {
        _userRepository = repo;
    }

    public override void Validate()
    {
        //Basic validation code
        if (string.IsNullOrEmpty(Username))
            throw new ValidationException("Username can not be a null or whitespace characters");
        if (string.IsNullOrEmpty(Password))
            throw new ValidationException("Password can not be a null or whitespace characters");

        //Complex validation code
        var user = _userRepository.GetUserByUsername(Username);
        if (user != null && user.id != id)
            throw new ValidationException("Username must be unique")
    }
}

不过这似乎是错的.使我的实体依赖于我的存储库似乎是一个坏主意(如果我错了,纠正我).但在实体中具有验证码是有意义的.放置复杂验证码的最佳位置在哪里?

解决方法

However this seems … well wrong. Making my entity depend on my repository seems like a bad idea (correct me if I am wrong).

一般来说,对存储库的依赖不是“错误的”,它有时是不可避免的.不过我觉得应该是一个例外,应尽可能避免.在您的情况下,您可能会重新考虑有这种依赖性.如果您想到这一点,“唯一性”不是实体本身的责任,因为实体不了解其他实体.那么为什么要实体执行这个规则呢?

But having the validation code in the entity makes sense. Where is the best place to put complex validation code?

我认为你可能会过度的“验证”.我将摆脱“验证”方法,并确保该对象首先不会进入“无效”状态.几个月前我也是类似的问题answered.

现在回到唯一性规则.我认为这是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);
}

客户端代码将会知道,在添加新用户之前,应该明确地检查唯一性,否则会崩溃.该组合在域代码中强制执行业务规则,但通常是不够的.作为附加的强制层,您可能希望在数据库添加UNIQUE约束或使用显式锁定.

猜你在找的C#相关文章