Generic Repository Pattern - Entity Framework, ASP.NET MVC and Unit Testing Triangle

We will see how we can implement Generic Repository Pattern with Entity Framework and how to benefit from that.
22 December 2011
5 minutes read

Related Posts

IMPORTANT NOTE:

I have a new blog post about Generic Repository implementation for Entity Framework. Please check it out instead of this one: Clean, Better, and Sexier Generic Repository Implementation for Entity Framework

NOTE:

Entity Framework DbContext Generic Repository Implementation Is Now On Nuget and GitHub: https://www.tugberkugurlu.com/archive/entity-framework-dbcontext-generic-repository-implementation-is-now-on-nuget-and-github

DRY: Don’t repeat yourself which is a principle of software development aimed at reducing repetition of information of all kinds, especially useful in multi-tier architectures. That’s what Wikipedia says. In my words, if you are writing the same code twice, follow these steps:

  • Step back.
  • Sit.
  • Think about it and dwell on that.

That’s what I have done for repository classes on my DAL projects. I nearly all the time use Entity Framework to reach out my database and I create repositories in order to query and manipulate data inside that database. There are some specific methods which I use for every single repository. As you can assume, those are FindBy, Add, Edit, Delete, Save. Let’s see on code what is my story here.

First approach (worst approach)

At first, long time ago, I have been creating all the single methods for each interface. For example below one is one of my repository interfaces:

I am giving the examples here with EF 4.2 but I was following this approach with EF 4 which does not contain DbContext class.

public interface IFooRepository {
        
    IQueryable<Foo> GetAll();
    Foo GetSingle(int fooId);
    IQueryable<Foo> FindBy(Expression<Func<Foo, bool>> predicate);
    void Add(Foo entity);
    void Delete(Foo entity);
    void Edit(Foo entity);
    void Save();
}

This repo is for Foo class I have (imaginary). Let's see the implementation for Bar class.

public interface IBarRepository {
    
    IQueryable<Bar> GetAll();
    Bar GetSingle(int barId);
    IQueryable<Bar> FindBy(Expression<Func<Bar, bool>> predicate);
    void Add(Bar entity);
    void Delete(Bar entity);
    void Edit(Bar entity);
    void Save();
}

Implementation nearly exactly the same here. Here is also an example of implementing one of these interfaces:

public class FooRepository : IFooRepository {

    private readonly FooBarEntities context = new FooBarEntities();

    public IQueryable<Foo> GetAll() {

        IQueryable<Foo> query = context.Foos;
        return query;
    }

    public Foo GetSingle(int fooId) {

        var query = this.GetAll().FirstOrDefault(x => x.FooId == fooId);
        return query;
    }

    public void Add(Foo entity) {

        context.Foos.Add(entity);
    }

    public void Delete(Foo entity) {

        context.Foos.Remove(entity);
    }

    public void Edit(Foo entity) {

        context.Entry<Foo>(entity).State = System.Data.EntityState.Modified;
    }

    public void Save() {

        context.SaveChanges();
    }
}

Also imagine this implementation for BarRepository as well. Indeed, there would be probably more repository classes for your project. After playing like that for a while I decided to do something different which still sucked but better.

A better approach but still sucks

I created a generic interface which saves me a lot of keystrokes. Here how it looks like:

public interface IGenericRepository<T> where T : class {
    
    IQueryable<T> GetAll();
    IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
    void Add(T entity);
    void Delete(T entity);
    void Edit(T entity);
    void Save();
}

And how I implemented in on repository interfaces:

public interface IFooRepository : IGenericRepository<Foo> {
    
    Foo GetSingle(int fooId);
}
public interface IBarRepository : IGenericRepository<Bar> {
    
    Bar GetSingle(int barId);
}

You can see that I only needed to implement GetSingle method here and others come with IGenericRepositoy<T> interface.

Where I implement these repository interfaces to my concrete classes, I still need to go over all the methods and create them individually. The repository class looked like as the same. So it leads me to a final solution which is the best one I can come up with so far.

Best approach

The generic interface I have created is still legitimate and usable here. In fact, I won’t touch the repository interfaces at all. What I did here first is to create an abstract class which implements IGenericReposity<T> interface but also accepts another type parameter defined in a generic declaration which is a type of DbConetxt class. Here is how it looks like:

public abstract class GenericRepository<C, T> : 
    IGenericRepository<T> where T : class where C : DbContext, new() {

    private C _entities = new C();
    public C Context {

        get { return _entities; }
        set { _entities = value; }
    }

    public virtual IQueryable<T> GetAll() {

        IQueryable<T> query = _entities.Set<T>();
        return query;
    }

    public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate) {

        IQueryable<T> query = _entities.Set<T>().Where(predicate);
        return query;
    }

    public virtual void Add(T entity) {
        _entities.Set<T>().Add(entity);
    }

    public virtual void Delete(T entity) {
        _entities.Set<T>().Remove(entity);
    }

    public virtual void Edit(T entity) {
        _entities.Entry(entity).State = System.Data.EntityState.Modified;
    }

    public virtual void Save() {
        _entities.SaveChanges();
    }
}

This is so nice because of some factors I like:

  • This implements so basic and ordinary methods
  • If necessary, those methods can be overridden because each method is virtual.
  • As we newed up the DbContext class here and expose it public with a public property, we have flexibility of extend the individual repositories for our needs.
  • As we only implement this abstract class only to our repository classes, it won’t effect unit testing at all. DbContext is not in the picture in terms of unit testing.

So, when we need to implement these changes to our concrete repository classes, we will end up with following result:

public class FooRepository :
    GenericRepository<FooBarEntities, Foo>, IFooRepository {

    public Foo GetSingle(int fooId) {

        var query = GetAll().FirstOrDefault(x => x.FooId == fooId);
        return query;
    }
}
public class BarReposiltory : 
    GenericRepository<FooBarEntities, Bar>, IBarRepository  {

    public Bar GetSingle(int barId) {

        var query = Context.Bars.FirstOrDefault(x => x.BarId == barId);
        return query;
    }
}

Very nice and clean. Inside BarRepository GetSingle method, as you see I use Context property of GenericRepository<C, T> abstract class to access an instance of DbContext.

So, how the things work inside our ASP.NET MVC project? this is another story but no so complicated. I will continue right from here on my next post.

UPDATE:

Here is the next post:

How to Work With Generic Repositories on ASP.NET MVC and Unit Testing Them By Mocking