Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repository Pattern Implementation

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?

like image 832
Scott Avatar asked Apr 17 '12 11:04

Scott


People also ask

What is repository pattern?

The Repository pattern. Repositories are classes or components that encapsulate the logic required to access data sources. They centralize common data access functionality, providing better maintainability and decoupling the infrastructure or technology used to access databases from the domain model layer.

What is repository in C sharp?

The Repository Design Pattern in C# Mediates between the domain and the data mapping layers using a collection-like interface for accessing the domain objects. In other words, we can say that a Repository Design Pattern acts as a middle layer between the rest of the application and the data access logic.

What is repository pattern in MVC?

The repository pattern is intended to create an abstraction layer between the data access layer and the business logic layer of an application. It is a data access pattern that prompts a more loosely coupled approach to data access.


1 Answers

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.

like image 163
jgauffin Avatar answered Oct 19 '22 02:10

jgauffin