HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Implementing the Repository Pattern

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
patternimplementingrepositorythe

Problem

I'm new to this pattern and I see arguments online about different implementations. I have the following code and it seems fine to me, but I'm wondering if having to pass the DBContext into the constructor would cause any issues down the line? I'm using this with EntityFramework (RECORD_TYPE is a table brought in from EF).

I'm a little newer to unit testing as well, so I'm thinking I would have to make a mock context in my unit tests that basically return a list of RECORD_TYPE objects that I create in the mock DBContext I make.

Am I missing any ideas with this?

public interface IRepository where T : class
{
    IQueryable All { get; }
    T Find(int id);
    void Save();
}

public class Repository : IRepository where T : class
{
    private DbContext context;

    public Repository(DbContext c)
    {
        context = c;
    }

    public IQueryable All { get { return context.Set(); } }

    public T Find(int id)
    {
        return context.Set().Find(id);
    }

    public void Save()
    {
        context.SaveChanges();
    }
}

public class RecordTypeRepository : Repository
{
    public RecordTypeRepository(DbContext context)
        : base(context)
    {
    }
}

Solution

In my opinion using the repository pattern is absolutely fine, for a number of reasons, not limited to:

  • It enables unit testing



  • Allows you to change EF for a another DB technology



The detail that you have to be careful of using the base class is that you make sure that you declare properties/variables via the interface and not via the base class. So consider this:

Good

public class Test{
    private IRepository _repo;
}


Bad

public class Test{
    private BaseRepository _repo;
}


With the actual code, I would suggest a number of changes:

  • The interface should have full CRUD operations



  • Try and use the same name for fetching a record (Consider Get() and Get(id) vs All() and Get(1). It makes it more natural to consumers)



  • The class Repository should be marked as abstract to stop you using it directly



  • The class Repository should probably be named EFBaseRepository



Typically, when I implement the pattern I create the interface followed by a class called BaseRepository that implements all the methods. The methods no nothing more than throw a NotSupportedException/NotImplementedException. This is because I might only want consumers to have read/update but not create. It does depend on the context of the application.

Code Snippets

public class Test{
    private IRepository<MyClass> _repo;
}
public class Test{
    private BaseRepository<MyClass> _repo;
}

Context

StackExchange Code Review Q#46639, answer score: 2

Revisions (0)

No revisions yet.