It seems that every example I find of the repository pattern, the implementation is different in some way. The following are the two examples I mainly find.
interface IProductRepository
{
IQueryable<Product> FindAll();
}
There is then usually another layer which talks to the repository and calls the FindAll() method and performs any operations such as finding products beginning with the letter ‘s’ or fetching products in a particular category.
The other example I find a lot put all of the find methods into the repository
interface IProductRepository
{
IEnumerable<Product> GetProductsInCategory(int categoryId);
IEnumerable<Product> GetProductsStartingWith(string letter);
IEnumerable<PromoCode> GetProductPromoCodes(int productId);
}
Which path do you recommend I take? Or what are the advantages/disadvantages from each other?
From my understanding having read http://martinfowler.com/eaaCatalog/repository.html the first approach seems to best reflect this?
The first one is horrible.
IQueryableis like a GOD object. It’s really hard to find a 100% complete implementation of it (even among all OR/Ms). You can expose your ORM directly instead of using it since you’ll probably get a leaky abstraction layer otherwise.Joel says it best (text is from the wikipedia article):
Joels blog entry
The second approach is much easier to implement and to keep the abstraction intact.
Update
Your repository is violating Single Responsibility Principle since it got two reasons to change. The first is if the Products API is changed and the other is if the PromoCode API is changed. You should imho use two different repositories like:
Changed things:
Findwhen several items are returned andGetif a single item is returned.Small well defined interfaces makes it easier to spot violations of the SOLID principles since classes the break the principles tend to get bloated constructors.