As you aware repository pattern will comes under creational patterns, Repository pattern can be used for achieving the abstraction between data access layer and business layer. In this article you can learn how to implement the Repository pattern in .NET applications.
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 Northwind repository:
public class CustomerRepository : IRepository<Customer>, IDisposable { #region Members private NorthwindContext _context; #endregion #region Ctor public CustomerRepository() { _context = new NorthwindContext(); } #endregion #region IRepository<Customer> Members public Customer GetById(int id) { return _context.Customers. Where(d => d.CustomerID == id). FirstOrDefault(); } public Customer[] GetAll() { return _context.Customers.ToArray(); } public IQueryable<Customer> Query(Expression<Func<Customer, bool>> filter) { return _context.Customers.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 customer 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 Customer repository:
IRepository<Customer> repository = new CustomerRepository(); foreach (var customer in repository.GetAll()) { Console.WriteLine(customer.ContactName); } foreach (var customer in repository.Query(c => c.CustomerID > 100)) { Console.WriteLine("customer with above 100 ID: {0}", customer.ContactName); } 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. testing can be achieve using the memory object instead of real database.
- 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
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. You can use same on any other data access frameworks as well and this is the beauty of the pattern.
There are lot of questions about returning of IQueryable object from Reporitory, It is not correct, You can get the right answer in below post with example.
Similar Topics:
- Implementing Unit of Work Pattern in .net
- Introduction To Model-View-ViewModel (MVVM) Pattern
- Implementing Abstract Factory Pattern in .net
- Implementing Factory Pattern in .net
- Test Driven Development guide
- Dependency Injection (DI) Pattern in asp.net
- Outlook Web Access corrupts HTML attachments
Trackbacks/Pingbacks