Thursday, June 5, 2014

The Repository Pattern


Use a repository pattern to separate the logic that retrieves the data from the data source and maps it to the business entities so that business logic can acts on this model.


In short we use the repository pattern as a layer of abstraction between a datasource and business logic.
E.g. We simply call EmployeeRepository.GetAll() to get all employee details and we don’t care how we get those employee details. That’s the repository’s job. If you ever need to change the way you retrieve employee details, there’s no need to change code other than inside the repository and everything still works fine.

Use of repository pattern is to make your code in the business layer totally independent of the way you access data. It shouldn't matter to the business logic whether the underlying datastore is in SQL server, any other database or coming from a web service. In the business layer I should be purely concerned about implementing the business rules.

In other words, repository pattern is meant for separation of concerns. We want to separate out the business logic and the data access code. This makes the code easier to test and maintain.



 Let me explain this with following example.
I have a database (say Company) with two database tables named Employee and Department.

Repository Pattern implementation for this example is as follows

i.                    Create an interface for Generic Repository of type T

namespace RepositoryPattern.BaseRepository
{
    public interface IRepository<T>
    {
        IQueryable<T> GetAll();
        T GetById(int id);
        void Insert(T entity);
        void Delete(T entity);
        void Save();
    }
}


ii.                  Implementation of this interface is as follows

Client will pass the instance of DbContext in the constructor. This DbContext object is nothing but the database context on which this Repository will perform its operations.

We retrieve the entity by calling the dataContext.Set<T>() method.
The resulting DbSet of type T is the entity table we will work on in rest of the methods in the class.

Rest of the method implementation is self explanatory, implemented using the Entity Framework.
  
namespace RepositoryPattern.BaseRepository
{
    public class Repository<T> : IRepository<T> where T : class
    {
        protected DbSet<T> DbSet;
        protected DbContext databaseContext;

        public Repository(DbContext dataContext)
        {
            DbSet = dataContext.Set<T>();
            databaseContext = dataContext;
        }

        #region IRepository<T> Members

        public IQueryable<T> GetAll()
        {
            return DbSet;
        }

        public T GetById(int id)
        {
            return DbSet.Find(id);
        }

        public void Insert(T entity)
        {
            DbSet.Add(entity);
        }

        public void Delete(T entity)
        {
            DbSet.Remove(entity);
        }

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

        #endregion
    }
}


iii.                Repositories for Entity specific operations
Based on this Generic Repository, we will create specific repositories for entity specific operations. These specific repositories will inherit above generic repository so they will have these basic operations (GetAll, GetById, Insert, Delete, Save etc) inherited from base repository. We can write some specific operations required in these repository which can apply some business logic if required.

namespace RepositoryPattern.Repositories
{
    public interface IEmployeeRepository
    {
       
    }

    public class EmployeeRepository : Repository<Employee>, IEmployeeRepository
    {
        public EmployeeRepository(DbContext dataContext)
            : base(dataContext)
        {

        }
    }
}


iv.               Using the Repositories
To use these repositories we will create instance of the required repository by providing it a datacontext object.
In following example I am creating instance of EmployeeRepository and providing CompanyEntities object as DbContext. Here CompanyEntities is a class auto-generated by EntityFramework model (.edmx file) and it derives from DbContext class.

public static void GetAllEmployees()
        {
            CompanyEntities entities = new CompanyEntities();
            var employeeRepository = new EmployeeRepository(entities);
            List<Employee> employees= employeeRepository.GetAll().ToList();
            foreach (var emp in employees)
            {
                Console.WriteLine(" Employee {0} Details", emp.EmpNo);
                Console.WriteLine("Emp Name : {0}", emp.EmpName);
                Console.WriteLine("Emp Designation : {0}", emp.Designation);
                Console.WriteLine("Emp Department : {0}", emp.Department.DeptName);
                Console.WriteLine("------------------------------------");
            }
            Console.WriteLine("#########################");
        }


v.                    Using Generic repository for basic operations without creating specific repository

To use generic repository instead of specific repository we will create generic repository object of type required entity.
E.g. In above case instead of creating object of EmployeeRepository(), we will create object of Repository<Employee>() and rest of the code would be same.


var employeeRepository = new Repository<Employee>(entities);

That is all about Repository pattern.
You can download code here

Hope this gives you a enough idea about Repository Pattern to use it in your projects. :)

1 comment: