Try Catch in Repository
None of the examples I have looked at for Repository Patterns include any kind of error handling. Why is this? Say for instance I have this:
public virtual TItem Insert<TItem>(TItem item) where TItem:class,new()
{
dbContext.Set<TItem>().Add(item);
try
{
dbContext.SaveChanges();
}
catch (DbUpdateException)
{
开发者_Python百科 return null;
}
return item;
}
An instance where we violate a constraint. I catch the DbUpdateException... Where would this error handling live if not in the repository itself?
In a properly-designed system, the constraints should never be able to be violated. Make your entities smarter: don't use blind auto-implemented setters, for example.
The repository is not the place to do data validation. The proper place is:
- If you are checking simply "contractual" constraints, e.g. "quantity should be a nonnegative integer" or "don't pass me a null customer," put the logic in the entity itself (either setters or constructor or mutating methods, as appropriate).
- If you are checking business logic, put it in specialized objects (DDD specifications if you wish) that abstract away that logic.
The only time these exceptions should come up is when you run your unit integration tests and you get a failure, which will reveal that either your database constraints are mismatched with your entity, or your entity is implemented incorrectly. So you definitely shouldn't catch
them.
For the most part, a repository doesn't need to worry about handling exceptions. The classes that are consuming the repositories should handle that. In your example, why would want to return null if an insert error occurs? Isn't that less clear than just throwing an exception?
For example, let's say we want to insert a record through the repository and then print out the new ID. Assume that the insert is going to fail for any reason.
var myNewItem = myRepository.Insert(myItem);
Console.WriteLine("MyItem added with ID: {0}", myNewItem.ID);
Following the pattern in your question, you'd get a NullReference
exception on the second line if the Insert
fails. That's a little strange. It's more clear to see the DbUpdateException
on the first line. It's also better to be able to count on Insert
always either returning a valid instance or throwing an exception.
精彩评论