Why use Repository Pattern or please explain it to me?

46,240

Solution 1

One thing is to increase testability and have a loose coupling to underlying persistance technology. But you will also have one repository per aggregate root object (eg. an order can be an aggregate root, which also have order lines (which are not aggregate root), to make domain object persistance more generic.

It's also makes it much easier to manage objects, because when you save an order, it will also save your child items (which can be order lines).

Solution 2

I don't think you should.

The Entity Framework is already an abstraction layer over your database. The context uses the unit of work pattern and each DBSet is a repository. Adding a Repository pattern on top of this distances you from the features of your ORM.

I talked about this in my blog post: http://www.nogginbox.co.uk/blog/do-we-need-the-repository-pattern

The main reason adding your own repository implementation is so that you can use dependency injection and make your code more testable.

EF is not very testable out of the box, but it's quite easy to make a mockable version of the EF data context with an interface that can be injected.

I talked about that here: http://www.nogginbox.co.uk/blog/mocking-entity-framework-data-context

If we don't need the repository pattern to make EF testable then I don't think we need it at all.

Solution 3

This picture makes it easy to understand

enter image description here

Solution 4

It's also an advantage to keep your queries in a central place; otherwise your queries are scattered around and are harder to maintain.

And the first point you mention: "To hide EF" is a good thing! For instance, saving logic can be hard to implement. There are multiple strategies that apply best in different scenarios. Especially when it comes to saving entities which also have changes in related entities.

Using repositories (in combination with UnitOfWork) can centralize this logic too.

Here are some videos with a nice explanation.

Solution 5

Repository systems are good for testing.

One reason being that you can use Dependency Injection.

Basically you create an interface for your repository, and you reference the interface for it when you are making the object. Then you can later make a fake object (using moq for instance) which implements that interface. Using something like ninject you can then bind the proper type to that interface. Boom you've just taken a dependence out of the equation and replaced it with something testable.

The idea is to be able to easily swap out implementations of objects for testing purposes Hope that makes sense.

Share:
46,240
King Chan
Author by

King Chan

Current Software Architecture mainly with .NET technology and Azure. I also have 10+ years experience as a full-stack developer/team leader, designed and developed numerous in-house desktop application/mobile application/web service. Currently locate in Tokyo, Japan and open for remote-work for any country.

Updated on October 10, 2020

Comments

  • King Chan
    King Chan over 3 years

    I am learning repository pattern and was reading Repository Pattern with Entity Framework 4.1 and Code First and Generic Repository Pattern - Entity Framework, ASP.NET MVC and Unit Testing Triangle about how they implement the repository pattern with Entity Framework.

    Saying

    •Hide EF from upper layer
    •Make code better testable

    Make code better testable I do understand, but why hide EF from upper layer?

    Looking at their implementation, it seems just wrap the entity framework with a generic method for query the entity framework. Actually what's the reason for doing this?

    I am assuming is for

    1. Loose coupling (that's why hide EF from upper layer?)
    2. Avoid repeat writting same LINQ statement for same query

    Am I understand this correctly?

    If I write a DataAccessLayer which is a class have methods

    QueryFooObject(int id)
    {
    ..//query foo from entity framework
    } 
    
    AddFooObject(Foo obj)
    {
    .. //add foo to entity framework
    }
    ......
    QueryBarObject(int id)
    {
    ..
    }
    
    AddBarObject(Bar obj)
    {
    ...
    }
    

    Is that also a Repository Pattern?

    Explaination for dummy will be great :)

  • King Chan
    King Chan over 12 years
    hmm, I still don't really understand why one repository per aggregate root object part. Isn't when I use entity framework to query an order object, the order will contains a list of order lines...? Sorry I am getting confuse...
  • Espen Burud
    Espen Burud over 12 years
    In the EF you can also save and retreive a complete aggregate root object with the ObjectContext.SaveChanges() method. But I wrote it because it's one of the advantages with the repository pattern.
  • King Chan
    King Chan over 12 years
    I see, now I understand. Thanks.
  • Slauma
    Slauma almost 12 years
    I really like this sentence in your blog post: "This layer of abstraction can distance you from the features of your ORM." One might say, this "distance" is the purpose of a repository. But for many questions people ask here about repo+EF I have the feeling they start with the abstraction without knowing the concrete features well enough. Abstraction starts with concrete things, not the other way around, and you actually have to know more than one thing (not only EF) to build a meaningful abstraction. Nobody had have the idea of an animal if he only had seen a dog but never a cat.
  • edgarian
    edgarian over 11 years
    I agree. I've always used the repository pattern, because that's how I was taught to do it. But recently I've realised that for 90% of use cases it's just unnecessary abstraction. In my last project I simply created an interface for the dbContext class that exposes the tables, savechanges function, and any other extras I might need.
  • Sam
    Sam over 11 years
    Whoever comes across this should know that the repository pattern is an anti-pattern. Ayende explains why: youtube.com/watch?v=0tlMTJDKiug
  • Michael12345
    Michael12345 over 10 years
    @SamDev thank you - it's taken me hours of surfing the web to find someone who can articulate why the proliferation of repository code I keep seeing gives me an ill feeling in my stomach.
  • eran otzap
    eran otzap over 8 years
    The repository abstraction has another purpose. It abstracts the manner in which your data is queried/created for you. what if for example you needed your entity to be constructed from additional data other then whats in your db. The layer using the repository would not change and would not be aware of where and how the data it received was constructed.
  • DDiVita
    DDiVita about 7 years
    I don't fully agree. EF is a very specific implementation of how you access data. Having an abstraction between your application and data access is vital. What if you decide to change ORMs or have several data sources as @eranotzap suggested? Regardless of EF not being very testable, it should not be the only reason to use an abstraction to EF.
  • sensei
    sensei almost 7 years
    you don't need repository pattern in entity framework core anymore for testing, unless you want to hide ef implementation from business layer.
  • sensei
    sensei almost 7 years
    @DDiVita with ef core, inmemory database was introduced, which expands testing, so if there is no other reason that for test to create repo, then i don't see why make it.
  • Blake Mumford
    Blake Mumford almost 7 years
    @DDiVita How often would you realistically change the ORM you are using?
  • DDiVita
    DDiVita almost 7 years
    It's not just for the ORM. We have several data contexts that are not using EF. For example we use our repos for Lucene, flat files, and mainframe access. It allows our infrastructure to be extended to other data sources. I feel the repository pattern is quite useful when working with multiple data sources. We can benefit for the same functionality no matter the persistence source.
  • Richard Garside
    Richard Garside about 6 years
    The db context in EF follows the Unit of Work pattern and each collection is similar to a repository. You can create a very simple wrapper around the context and still unit test.
  • Shaiju T
    Shaiju T almost 6 years
    So Whats your final conclusion to not use repository pattern with EF ? If yes , then how would you do DI and what if you want to use Oracle as data source , see this post from @Darin Dimitrov which uses repository pattern to switch to different data source using DI.
  • aggsol
    aggsol almost 5 years
    Please stay away from the repository pattern, you are likely find better way on your own.
  • Manish Jain
    Manish Jain over 4 years
    you should explain code you have written above for asked question.
  • BornToCode
    BornToCode over 3 years
    What about SRP? If you're using EF context directly within your services without any repository and you have complex queries (with complex where clauses and selects and grouping) suddenly you have all this complex logic/query inside a class that is not responsible for all of that. Without a dedicated repository you can no longer test that this complex query "logic" works correctly without invoking the entire service.
  • Richard Garside
    Richard Garside about 3 years
    @BornToCode I store my complex queries in extension methods nogginbox.co.uk/blog/extension-methods-filter-iqueryable
  • carloswm85
    carloswm85 about 2 years
    Would you mind to elaborate? What's DbContext, ISS, Unit of Work? Just for the sake of improving the picture explanation.