Agenda:

In this article, I am going to discuss well known Repository pattern. It also briefs benefits of it in software architecture process. I have also listed out certain keypoints, we need to keep in mind while implementing it in any project. I have used C# as base language. Let us get started.

Introduction

By the books, Repositories are the classes which encapsulate the logic required to access data source.

It performs the tasks of an intermediary between the domain model layers and data mapping, acting in a similar way to a set of domain objects in memory.
It can be visualized as shown in image below:

Motive

  • Can you recall a scenario of applying same LINQ to DbSet everytime needed ? Repository help you centrailize the data access logic and hence minimizes duplicate query logic.
  • What if tomorrow you want to change the data access framework? Respository pattern make that task easy for you. It decouples application from persistance framework.
  • You can easily mock repositories and this is how it makes easy to test the data access layer.

Keypoints

  • A repository should not have semantic of database but a collection. i.e. Add, Remove, Find, GetAll etc.
  • You must have one Repository per aggregate not per entity.
  • Repository methods should return IEnumberable not IQueryable.

Demo

Lets have an example of User Repository

IRepository

  1. interface IRepository<T> where T : class
  2. {
  3. T GetById(int id);
  4. IEnumerable<T> GetAll();
  5. void Add(T entity);
  6. void AddRange(IEnumerable<T> entities);
  7. void Remove(T entity);
  8. void RemoveRange(IEnumerable<T> entities);
  9. }

IUserRepository

  1. interface IUserRepository : IRepository<User>
  2. {
  3. User GetUserWithAddress(int id);
  4. }

UserRepository

  1. class UserRepository : Repository<User>, IUserRepository
  2. {
  3. public UserRepository(SampleContext context) : base(context) {
  4.  
  5. }
  6.  
  7. public User GetUserWithAddress(int id)
  8. {
  9. return SampleContext.Users.Include("Address").SingleOrDefault(x => x.UserId == id);
  10. }
  11. public SampleContext SampleContext
  12. {
  13. get
  14. {
  15. return Context as SampleContext;
  16. }
  17. }
  18. }

IUnitOfWork

  1. interface IUnitOfWork
  2. {
  3. IUserRepository User { get; }
  4. int Complete();
  5. }

UnitOfWork

  1. class UnitOfWork : IUnitOfWork
  2. {
  3. private readonly SampleContext _context;
  4.  
  5. public UnitOfWork(SampleContext context)
  6. {
  7. _context = context;
  8. User = new UserRepository(_context);
  9. }
  10.  
  11. public IUserRepository User { get; private set; }
  12.  
  13. public int Complete()
  14. {
  15. return _context.SaveChanges();
  16. }
  17.  
  18. public void Dispose()
  19. {
  20. _context.Dispose();
  21. }
  22. }

For full source code refer rgilotra

Conclusion:

In this article we learnt significance of Repository Pattern and its implementation in Asp.Net MVC using EF and UoW. I have tried to keep it straight, simple and short. Your feedbacks are welcome.

Good Bye 👋 !! until I write again. Code well, Cook good.