Repository Pattern Implementation

c#, design-patterns

Solution

The first one is horrible. `IQueryable` is 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):

In Spolsky's article, he calls attention to many examples of abstractions that work most of the time, but where a detail of the underlying complexity cannot be ignored, and thus drives complexity into the software that was supposed to be simplified by the abstraction itself

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:

interface IProductRepository
{
    IEnumerable<Product> FindForCategory(int categoryId);
    IEnumerable<Product> FindAllStartingWith(string letter);
}

interface IPromoCodeRepository
{
    IEnumerable<PromoCode> FindForProduct(int productId);
}

Changed things:

- I tend to begin methods with `Find` when several items are returned and `Get` if a single item is returned.

- Shorter method names = easier to read.

- Single responsibility. It's easier to tell what the classes that use the repositories have for dependencies.

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.

Problem

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?

Original source

Related problems