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.
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);
Hope this
gives you a enough idea about Repository Pattern to use it in your projects. :)
Great Work.. Keep Sharing ..:)
ReplyDelete