假设我有存储库:
interface IRepo
{
Foo Get(int id);
void Add(Foo f);
}
现在,要求我只能拥有一个Foo
具有给定属性的人,比如说Id
...。显然,如果我IRepo
使用一些 SQL 后端实现并映射Foo.Id
到主键,我会免费获得类似的东西——我可能会以某种PKViolationException
. 但这正在变得特定于实现,所以无论我在哪里使用这个IRepo
实现并开始捕获这些异常,我都会失去松散耦合的好处。
现在,我将如何解决这个问题?我是否应该添加某种服务层,首先检查对象是否存在,然后抛出一些独立于存储库的异常?
class Service
{
IRepo repo;
public void AddFoo(Foo foo)
{
if(repo.Get(foo.Id) != null)
repo.Add(foo);
else
throw new FooAlreadyExistsException(foo.Id);
}
}
这个解决方案似乎很糟糕,因为它repo.Add(foo)
仍然会引发一些异常,尤其是在检查之后(通过其他一些活动)添加了具有给定 ID 的对象时,所以我只是向我的基础架构添加了一个额外的调用,而几乎没有好处。
似乎我应该小心并IRepo
在考虑到这种异常的情况下实现(可以捕获PKViolationException
并将其转换FooAlreadyExistsException
为示例 SQL 实现),但是如何确保每个IRepo
实现都遵循这样的规范?
您一般如何解决这些问题?