Using Repository Pattern with Entity Framework
Using Repository Pattern with Entity Framework
One of the tools
for reaching for
persistence
ignorance is to
build a facade between
the data access layer and
your business logic. Such facade will prevent the knowledge of
how the data access is working and with which technology. That
abstraction can be achieved by using the Repository Pattern.
In the post I’ll show how you can use the Repository Pattern in order
to make an abstraction layer on top of Entity Framework.
The Repository Interface
When we want to use the Repository Pattern we
start with an interface which will be our data access facade.
I’ll be using the following interface in my example:
public interface IRepository<T>
{
T GetById(int id);
T[] GetAll();
IQueryable<T> Query(Expression<Func<T, bool>> filter);
}
This interface only include some of the functionality which I’ll
put in a repository. You may notice that I removed any CUD
(Create/Update/Delete) operations. In a follow up post I’ll show
how to implement these operations by using the Unit of Work
pattern.
A Repository Implementation
The following is a naive implementation for a department repository:
public class DepartmentRepository : IRepository<Department>, IDisposable
{
#region Members
private SchoolEntities _context;
#endregion
#region Ctor
public DepartmentRepository()
{
_context = new SchoolEntities();
}
#endregion
#region IRepository<Department> Members
public Department GetById(int id)
{
return _context.Departments.
Where(d => d.DepartmentID == id).
FirstOrDefault();
}
public Department[] GetAll()
{
return _context.Departments.ToArray();
}
public IQueryable<Department> Query(Expression<Func<Department, bool>> filter)
{
return _context.Departments.Where(filter);
}
#endregion
#region IDisposable Members
public void Dispose()
{
if (_context != null)
{
_context.Dispose();
}
GC.SuppressFinalize(this);
}
#endregion
}
This is a naive implementation since I hold a context inside my
department repository. A better solution will be to create a
context helper that will be used in order to create contexts when
they are needed. After we have the implementation we can start
using it.
The following code demonstrate how we can use the department
repository:
IRepository<Department> repository = new DepartmentRepository();
foreach (var department in repository.GetAll())
{
Console.WriteLine(department.Name);
}
foreach (var department in repository.Query(d => d.Budget > 150000))
{
Console.WriteLine("department with above 150000 budget: {0}",
department.Name);
}
Console.ReadLine();
Why to use the Repository Pattern?
There are a lot of reasons for using the Repository Pattern.
For example:
- Testability. Using the pattern we can create stubs that
can replace the real data access objects. This can
help us to test our business logic without concerning what the
data access is doing.
- Abstraction. Using the pattern we create an abstraction above
our data access functionality. This abstraction can help us when we
want to change the implementation of the data access without
affecting our business logic code. For example, I had to change
implementation of data access with a call to a web service. Using
the pattern I only needed to change the object that I used and that is
it.
- Dependency Injection. Using the pattern we can use DI containers to
inject the relevant object that we want to use in the code.
Summary
Lets sum up, the Repository Pattern is a very useful pattern to use
when we build data access layers. Like all other patterns sometimes
it can be an overkill in abstraction (in particular in small and simple applications).
In the post I showed one way to create a repository on top of Entity Framework.
I could have used any other data access frameworks as well and this is the beauty
of the pattern. In a follow up post I’ll explain what is the Unit of Work pattern and
will continue building the repository I used in this post so stay tuned.