我有这样的逻辑,在将库存保存到数据库之前,我将检查库存中是否有相同的库存代码。我的问题是我应该在服务层或存储库层中放置逻辑。这是示例代码:
选项1:放入服务层,我将IsAccountAlreadyExists方法放在服务层中
public override void Save(AccountInfo accountInfo)
{
using (var scope = new TransactionScope())
{
if(this.IsAccountAlreadyExists(accountInfo))
{
throw new AccountAlreadyExistedException(
"Account Code : " + accountInfo.AccountCode +
" already existed.");
}
accountRepository.Save(accountInfo);
scope.Complete();
}
}
选项2:我将把IsAccountAlreadyExists逻辑移动到存储库层。
public override void Save(AccountInfo accountInfo)
{
try
{
using (var scope = new TransactionScope())
{
accountRepository.Save(accountInfo);
scope.Complete();
}
}
catch(AccountAlreadyExistedException e)
{
...
}
}
你有什么看法?
答案 0 :(得分:6)
我认为这是三层(定义了连接每个部分的接口):
这样,如果您选择以其他方式存储数据,验证逻辑不会随之丢失。
同样,如果您决定提供不同形式的客户端访问,则无需复制大量逻辑即可实现。
答案 1 :(得分:5)
服务 - 存储库模式可能有点主观。当然有不好的/完全错误的例子(虽然这个不是),但通常情况下,这取决于个人偏好。
我倾向于遵循的模式是存储库层应该99%专门用于数据源的读写 - 删除操作。我的存储库层执行的唯一验证是模型上的非常低级别的验证:这通常通过Model.IsValid方法完成。它仅检查所需字段以及这些字段的格式/基本内容(例如,应该保留和发送电子邮件的字段的注册检查)。存储库层不会尝试理解这些错误 - 如果模型无效,那么它会抛出异常,并结束它的处理。
应在服务层执行业务逻辑检查。如果允许将User对象“分配”到特定模型(“Joe拥有记录X”),则服务层应执行检查以确保允许Joe拥有该记录等。要完成,我的服务层通常是还会检查模型上的IsValid方法,以预先防止数据层异常。
我对您的示例代码的唯一评论是方法名称“保存” - 这太模糊了。我更喜欢创建/插入和更新 - 很明显,前者将导致创建一个新记录(偶尔我用一个新值覆盖对象的Id字段),而后者应该更新记录,如果没有传递Id值,则抛出异常。
答案 2 :(得分:2)
既然你提出了意见,那么就是这样。 :-) 将验证逻辑放在最接近数据的最低层。所以在这种情况下,逻辑应该在Repository中。如果愿意,服务可以捕获异常并翻译它。但是“帐户应该是唯一的”标准是存储库,IMO的一个特征。
答案 3 :(得分:1)
我把它放在服务层。存储库处理持久性逻辑。
服务于其他对象以完成工作是服务职责。
答案 4 :(得分:0)
我更喜欢将检查放在最接近数据的地方 - 所以在这种情况下,这将是数据库。
我会根据你所做的条件制定一个独特的约束,以确保帐户不存在。这将确保没有人可以绕过我的中间层并插入错误的数据。
然后我可以将检查放在存储库层中作为额外的预防措施。