As far as I've been studying the Repository pattern, the "repositories" should be responsible for data persisting and basic querying tasks, and only for that. So in a typical repository I see something like this:
public interface IProductRepository {
Product GetByID(int id);
void Add(Product item);
void Update(Product item);
void Delete(Product item);
}
But I wonder what if one uses an ORM tool like DevExpress' XPO, a repository implementation would mostly consist of one-liner methods. Does it make sense to still create this abstraction level beside XPO?
One could point out the mocking and unit testing capabilities, but for example XPO provides a powerful in-memory persistence feature, which is perfect for unit testing in 99% of times.
I think I could mention EF or NHibernate as well, those have similar features.
An additional question: if - let's say - I don't implement the repository pattern in this manner, where shall I put more complex queriyng (for example based on complex criteria or user roles), or more complex item saving logic (with logging, validation, etc.)?
Thanks for any help.
UPDATE
What about defining a generic repository interface which type-independently addresses CRUD operetaions like this:
public interface IRepository : IDisposable {
T GetByID<T>(int id);
IQueryable<T> Query<T>();
T Create<T>();
void Update<T>(T item);
void Delete<T>(T item);
}
Then I can implement it easily with with XPO, EF, or whatever ORM I choose, even with JSON text files. Is it a good middle-way solution, or does it smell? The only drawback I can see is where would I put those more complex operations mentioned above, but probably I could inherit special interfaces from this when needed.
But I wonder what if one uses an ORM tool like DevExpress' XPO, a repository implementation would mostly consist of one-liner methods. Does it make sense to still create this abstraction level beside XPO?
It depends on coding a technology-specific ignorant domain when it comes to persist and read your domain objects.
You might think that XPO or any other OR/M does a lot of wrapping and abstraction, so it sounds stupid the repository pattern because is an unnecessary layer.
Well, I would say that one of most strong points when you decide to use the repository pattern is turning your domain agnostic about how it gets translated into what underlying store understands. An OR/M adds a lot of details and dependencies which may be hardly changed if you spread them across your domain code.
Have you ever realized that repository pattern might be the right tool to decide what persists your data based on a simple configuration switch (inversion of control)? I don't think about this for testing purposes: choose repository pattern because you want to define how your domain talks to data in a single point.
You can even make your code work with more than one version of the same OR/M technology, because newer versions might not fit an old requirement, but new domain operations are still able to instantiate a new repository version which takes advantage of newer version optimizations and capabilities!
Yes, even if your repositories have one-liner methods, they're still useful. Fight for the future!
What about defining a generic repository interface which type-independently addresses CRUD operetaions like this:
This is perfectly valid: it's called generic repository. In fact, in my own developments I'm always using this pattern.