我有一个与实体验证有关的问题.例如,有一个用户可以通过电子邮件和密码注册到系统中.业务规则说:
>电子邮件必须有效(必须符合电子邮件格式)且独一无二;
>密码应在6到20个字符之间.
我最初的想法是将验证放在User.Register(电子邮件,密码)中.这种方法的主要优点是用户通过验证注册数据的正确性来控制注册方式.缺点是电子邮件唯一性验证需要调用UserRepository,因此用户可能依赖于其存储库.要解决此问题,可能会将某些BusinessRule对象的电子邮件和密码验证考虑在内.因此,User.Register()方法中的验证可能如下所示:
var emailValidationErrors = _emailRule.Validate(email); var passwordValidationErrors = _passwordRule.Validate(password);
其中_emailRule和_passwordRule可能作为构造函数参数传递:User(EmailRule emailRule,PasswordRule passwordRule).
在这个casse中,User不直接耦合到UserRepository.通过这种方式,规则在域中明确显示,这使其更具表现力.
您可以实现封装此域的域服务.通常在DDD中,当业务逻辑超出单个聚合的范围时,您将使用域服务;在这种情况下,它是唯一性检查.那么,我要做的是:
public class UserRegistrationService : IUserRegistrationService { private readonly IUserRespository _userRepository; public void Register(string email,string password) { if (!_userRepository.DoesEmailExist(email)) throw new Exception("Email already registered"); User user = User.Create(email,password); _userRepository.Save(user); } }
此外,如果您担心在注册服务之外调用User.Create并因此转义唯一性检查,您可以将User.Create方法设置为internal,这意味着创建用户的唯一方法是通过RegistrationService.