我有一个这样创建用户的帐户对象;
public class Account
{
public ICollection<User> Users { get; set; }
public User CreateUser(string email)
{
User user = new User(email);
user.Account = this;
Users.Add(user);
}
}
在我的服务层创建新用户时,我调用此方法。但是,有一条规则是用户的电子邮件必须是该帐户唯一的,那么这在哪里呢?对我来说,它应该在 CreateUser 方法中使用额外的一行来检查电子邮件是否对帐户是唯一的。
但是,如果要这样做,则需要加载该帐户的所有用户,这对我来说似乎有点开销。最好在数据库中查询用户电子邮件 - 但在方法中这样做需要帐户对象中的存储库,不是吗?也许答案是从存储库加载帐户而不是这样做;
var accountRepository.Get(12);
//instead do
var accountRepository.GetWithUserLoadedOnEmail(12, "someone@example.com");
然后帐户对象仍然可以检查电子邮件的用户集合,如果找到它就会被急切地加载。
这行得通吗?你会怎么办?
我使用 NHibernate 作为 ORM。
最佳答案
首先,我认为您不应该使用异常来处理“正常”业务逻辑,例如检查重复的电子邮件地址。这是一个很好的文档反模式,最好避免。保持对数据库的约束并处理任何重复的异常,因为它们无法避免,但请尝试通过检查将它们保持在最低限度。我不建议锁定 table 。
其次,你在这个问题上打了DDD标签,我就用DDD的方式来回答。在我看来,您需要域服务或工厂。一旦您将此代码移动到域服务或工厂中,您就可以将 UserRepository 注入(inject)其中并调用它以查看用户是否已使用该电子邮件地址存在。
像这样的东西:
public class CreateUserService
{
private readonly IUserRepository userRepository;
public CreateUserService(IUserRepository userRepository)
{
this.userRepository = userRepository;
}
public bool CreateUser(Account account, string emailAddress)
{
// Check if there is already a user with this email address
User userWithSameEmailAddress = userRepository.GetUserByEmailAddress(emailAddress);
if (userWithSameEmailAddress != null)
{
return false;
}
// Create the new user, depending on you aggregates this could be a factory method on Account
User newUser = new User(emailAddress);
account.AddUser(newUser);
return true;
}
}
这使您可以稍微分离职责并使用域服务来协调事情。希望有帮助!
关于domain-driven-design - 在哪里检查用户电子邮件尚不存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1233618/