patterncsharpMinor
Implementing the Repository Pattern
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?
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:
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
Bad
With the actual code, I would suggest a number of changes:
Typically, when I implement the pattern I create the interface followed by a class called
- 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()andGet(id)vsAll()andGet(1). It makes it more natural to consumers)
- The class
Repositoryshould be marked as abstract to stop you using it directly
- The class
Repositoryshould probably be namedEFBaseRepository
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.