我有一个帐户对象,可以像这样创建用户;
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, "[email protected] /cdn-cgi/l/email-protection");
然后,帐户对象仍然可以检查用户集合中的电子邮件,如果找到,它就会立即加载。
这有效吗?你会怎么办?
我使用 NHibernate 作为 ORM。
首先,我认为您不应该使用异常来处理“正常”业务逻辑,例如检查重复的电子邮件地址。这是一个有据可查的反模式,最好避免。保持对数据库的约束并处理任何重复的异常,因为它们无法避免,但尝试通过检查将它们保持在最低限度。我不建议锁定桌子。
其次,你在这个问题上贴上了DDD标签,所以我就用DDD的方式来回答。在我看来,您需要域服务或工厂。一旦您将此代码移动到域服务或工厂中,您就可以将 UserRepository 注入其中并调用它以查看是否已存在具有该电子邮件地址的用户。
像这样的事情:
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;
}
}
这允许您稍微分离职责并使用域服务来协调事物。希望有帮助!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)