×

iFour Logo

Ultimate guide for implementing Repository pattern and Unit of work for .NET core

Kapil Panchal - October 15, 2020

Listening is fun too.

Straighten your back and cherish with coffee - PLAY !

  • play
  • pause
  • pause
Ultimate guide for implementing Repository pattern and Unit of work for .NET core

The repository and unit of work patterns are deliberated to generate alayer between the data access layer and the business logic layer of any application. Executing these patterns can assistwrapping of your application from changes in the data store and can accelerate automated unit testing or test-driven development (TDD).

 

Table of Content


What is the Repository pattern?


The Repository pattern is used to separates the data access layer and business logic in your application. It creates the abstraction layer between data access layer and business logic layer of your application.

The repository offers a collection of an interface by providing methods to add,modify, remove, and fetch domain objects.

Assume that there is the data logic on the context which is used by the three controllers so for that you have to write the same logic three times at different places.

This problem will be solved by the repository pattern. It provides the codere-usability, maintainability, and scalability.

What is Unit of Work pattern?


When there are multiple repositories that need to be invoked or process for a single request which shares a common context for that we need to implement the Unit of Work.

We can implement the repository effectively with the help of the unit of work.

When a set of databases commit operations in that case we cannot just go and call the SaveChanges() method every time. For that, we are going tocluster the related repository into a single unit call Unit of Work.

Repository and Unit of Work pattern design


diagram

Advantages

  • Repository centralize your data logic and service logic.
  • Reduce the code, provides flexibility architecture.
  • Unit of Work provides the effective implementation of repositories. And Unit of Work is a cluster of the repositories.

 

Example

For example, there is a customer repository and a customer repositoryinterface.

 
namespace WebApplication16.Repository
{
interfaceICustomerRepo
{
//definition of your method
}
}
					

This is the customer repository interface. Declare your method here and implement that method in repository.

 
namespace WebApplication16.Repository
{  
publicclassCustomerRepo : ICustomerRepo
{          
DbContext context;
public CustomerRepo(DbContext ctx)
{
 this.context = ctx;
}  
}
}
			  

This is the customer repository that implements the method from ICustomerRepo.
These repository work on their dbcontext instance that is used to perform the operations onto the database using Entity Framework Core.

So, we use the Unit of Work pattern to group the all common (CRUD) operations like create, retrieve, update, and delete and place it in the generic repository.

In IRepo, we can declare two method for add and remove as shown below.

 
Step 1: - Create generic repository interface
 
namespace WebApplication16.Repository
{
interfaceIRepowhere T : class
{
void Add(T entity);
void Delete(T entity);        
}
}
		       

We have defined two method Add and Delete in IRepo and implement them in Repository named Repo as shown below.

 
Step 2: - Create generic repository
 
namespace WebApplication16.Repository
{
publicclassRepo : IRepowhere T : class
{
protectedreadonly DbSet _context;
public Repo(DbContext context)
{
  _context = context.Set();
}
publicvoid Add(T entity)
{
 _context.Add(entity);
}
publicvoid Delete(T entity)
{
_context.Remove(entity);
}        
}
}
			  

IRepo accept the generic type reference T of class type and implement that method in repository and works on context passed on to it.

The entity set is created using context.set() method which returns the specific dbset.

Now make use of these Interface repositories to link with customer repository as shown below.

 
Step 3: - Create customer repository interface
 
namespace WebApplication16.Repository
{
interfaceICustomerRepo : IRepo
{
//declare your methods
}
}
			  

ICustomerRepo repository interface inherits the IRepo.

 
Step 4: - Create customer repository
 
namespace WebApplication16.Repository
{
publicclassCustomerRepo : Repo, ICustomerRepo
{
publicCustomerRepo(Context ctx) : base(ctx)       
{
					  
  
}        
}
}
			  

Now CustomerRepo class from Repo with their type reference Customer.

We have passed the context in the constructor which is derived from the baseconstructor.

Create the Unit of Work class to group all repositories.

 
Step 5: - Create Unit of Work Interface
 
 namespace WebApplication16.Repository
{
interfaceIUoW : IDisposable
{
ICustomerRepo CustomerRepo {get;}
intCommit ();
}
}
				

We can create the IUoW interface which extends the IDisposable interface that provides a mechanism for releasing unmanaged resources.

 
Step 6: - Create Unit of Work Class
 
namespace WebApplication16.Repository
{
publicclassUow : IUoW
{
privatereadonly Context _context;
private IRepo customer;
public Uow(Context context)
{
this._context = context;            
}
public ICustomerRepo CustomerRepo
{
get
{
returnnew CustomerRepo(_context);
}
}
publicint Commit()
{
return _context.SaveChanges();
}
publicvoid Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
				
 
protectedvirtualvoid Dispose(bool disposing)
{
if (disposing)
{
 _context.Dispose();
}
}
}
}
				
				

Unit of Work class (Uow) extends the unit of work interface (IUoW). Which has a commit method and one property.

We have passed the context in the Uow constructor that invokes the commit method in which respective operations will be saved into the database.

Now create the controller which uses the Unit of Work interface and perform the operations on database.

Planning to Hire Dedicated ASP.Net Core Developer ? Your Search ends here.

 
Step 7: - Create Constructor
 
namespace WebApplication16.Controllers
{
[Route("api/[controller]")]
[ApiController]
publicclassCustomerController : ControllerBase
{
private IUoW _unitOfWork;
public CustomerController(IUoW unitOfWork)
{
_unitOfWork = unitOfWork;
}
[HttpGet]
public IEnumerable Get()
{
return _unitOfWork.CustomerRepo.GetAll();
}        
[HttpGet("{id}")]
public Customer Get(int id)
{
return _unitOfWork.CustomerRepo.GetCustomerById(id);
}
[HttpPost]
{
var customer = new Customer
{
Id = 1,FirstName = "Raj",LastName = "Patel", Age = 22
} ;            
_unitOfWork.CustomerRepo.Add(customer);
_unitOfWork.Commit();
return Ok();
            
}
}
				 

We have created the customer controller that extends controller base.

In the customer controller constructor pass the Unit of Work interface instance. Now Define your method to get, add, and delete method from the repository.

In this way, we can create the simple Unit of Work pattern for our application which helps us to improve the database transaction time.

Conclusion


In this blog, we have depicted how to implement the repository and Unit of Work pattern. Implementing both patterns can increase the testability, maintainability, and flexibility in architecture. Hope you understand it briefly.

Ultimate guide for implementing Repository pattern and Unit of work for .NET core The repository and unit of work patterns are deliberated to generate alayer between the data access layer and the business logic layer of any application. Executing these patterns can assistwrapping of your application from changes in the data store and can accelerate automated unit testing or test-driven development (TDD).   Table of Content 1. What is the Repository pattern? 2. What is Unit of Work pattern? 3. Repository and Unit of Work pattern design 4. Advantages 5. Conclusion What is the Repository pattern? The Repository pattern is used to separates the data access layer and business logic in your application. It creates the abstraction layer between data access layer and business logic layer of your application. The repository offers a collection of an interface by providing methods to add,modify, remove, and fetch domain objects. Assume that there is the data logic on the context which is used by the three controllers so for that you have to write the same logic three times at different places. This problem will be solved by the repository pattern. It provides the codere-usability, maintainability, and scalability. What is Unit of Work pattern? When there are multiple repositories that need to be invoked or process for a single request which shares a common context for that we need to implement the Unit of Work. We can implement the repository effectively with the help of the unit of work. When a set of databases commit operations in that case we cannot just go and call the SaveChanges() method every time. For that, we are going tocluster the related repository into a single unit call Unit of Work. Repository and Unit of Work pattern design Advantages Repository centralize your data logic and service logic. Reduce the code, provides flexibility architecture. Unit of Work provides the effective implementation of repositories. And Unit of Work is a cluster of the repositories. Read More: 13 Important .net Core Libraries That Every .net Core Developer Should Know   Example For example, there is a customer repository and a customer repositoryinterface.   namespace WebApplication16.Repository { interfaceICustomerRepo { //definition of your method } } This is the customer repository interface. Declare your method here and implement that method in repository.   namespace WebApplication16.Repository { publicclassCustomerRepo : ICustomerRepo { DbContext context; public CustomerRepo(DbContext ctx) { this.context = ctx; } } } This is the customer repository that implements the method from ICustomerRepo. These repository work on their dbcontext instance that is used to perform the operations onto the database using Entity Framework Core. So, we use the Unit of Work pattern to group the all common (CRUD) operations like create, retrieve, update, and delete and place it in the generic repository. In IRepo, we can declare two method for add and remove as shown below.   Step 1: - Create generic repository interface   namespace WebApplication16.Repository { interfaceIRepowhere T : class { void Add(T entity); void Delete(T entity); } } We have defined two method Add and Delete in IRepo and implement them in Repository named Repo as shown below.   Step 2: - Create generic repository   namespace WebApplication16.Repository { publicclassRepo : IRepowhere T : class { protectedreadonly DbSet _context; public Repo(DbContext context) { _context = context.Set(); } publicvoid Add(T entity) { _context.Add(entity); } publicvoid Delete(T entity) { _context.Remove(entity); } } } IRepo accept the generic type reference T of class type and implement that method in repository and works on context passed on to it. The entity set is created using context.set() method which returns the specific dbset. Now make use of these Interface repositories to link with customer repository as shown below.   Step 3: - Create customer repository interface   namespace WebApplication16.Repository { interfaceICustomerRepo : IRepo { //declare your methods } } ICustomerRepo repository interface inherits the IRepo.   Step 4: - Create customer repository   namespace WebApplication16.Repository { publicclassCustomerRepo : Repo, ICustomerRepo { publicCustomerRepo(Context ctx) : base(ctx) { } } } Now CustomerRepo class from Repo with their type reference Customer. We have passed the context in the constructor which is derived from the baseconstructor. Create the Unit of Work class to group all repositories.   Step 5: - Create Unit of Work Interface   namespace WebApplication16.Repository { interfaceIUoW : IDisposable { ICustomerRepo CustomerRepo {get;} intCommit (); } } We can create the IUoW interface which extends the IDisposable interface that provides a mechanism for releasing unmanaged resources.   Step 6: - Create Unit of Work Class   namespace WebApplication16.Repository { publicclassUow : IUoW { privatereadonly Context _context; private IRepo customer; public Uow(Context context) { this._context = context; } public ICustomerRepo CustomerRepo { get { returnnew CustomerRepo(_context); } } publicint Commit() { return _context.SaveChanges(); } publicvoid Dispose() { Dispose(true); GC.SuppressFinalize(this); }   protectedvirtualvoid Dispose(bool disposing) { if (disposing) { _context.Dispose(); } } } } Unit of Work class (Uow) extends the unit of work interface (IUoW). Which has a commit method and one property. We have passed the context in the Uow constructor that invokes the commit method in which respective operations will be saved into the database. Now create the controller which uses the Unit of Work interface and perform the operations on database. Planning to Hire Dedicated ASP.Net Core Developer ? Your Search ends here. See here   Step 7: - Create Constructor   namespace WebApplication16.Controllers { [Route("api/[controller]")] [ApiController] publicclassCustomerController : ControllerBase { private IUoW _unitOfWork; public CustomerController(IUoW unitOfWork) { _unitOfWork = unitOfWork; } [HttpGet] public IEnumerable Get() { return _unitOfWork.CustomerRepo.GetAll(); } [HttpGet("{id}")] public Customer Get(int id) { return _unitOfWork.CustomerRepo.GetCustomerById(id); } [HttpPost] { var customer = new Customer { Id = 1,FirstName = "Raj",LastName = "Patel", Age = 22 } ; _unitOfWork.CustomerRepo.Add(customer); _unitOfWork.Commit(); return Ok(); } } We have created the customer controller that extends controller base. In the customer controller constructor pass the Unit of Work interface instance. Now Define your method to get, add, and delete method from the repository. In this way, we can create the simple Unit of Work pattern for our application which helps us to improve the database transaction time. Conclusion In this blog, we have depicted how to implement the repository and Unit of Work pattern. Implementing both patterns can increase the testability, maintainability, and flexibility in architecture. Hope you understand it briefly.

Build Your Agile Team

Enter your e-mail address Please enter valid e-mail

Categories

Ensure your sustainable growth with our team

Talk to our experts
Sustainable
Sustainable
 

Blog Our insights

Power Apps vs Power Automate: When to Use What?
Power Apps vs Power Automate: When to Use What?

I often see people asking questions like “Is Power App the same as Power Automate?”. “Are they interchangeable or have their own purpose?”. We first need to clear up this confusion...

Azure DevOps Pipeline Deployment for Competitive Business: The Winning Formula
Azure DevOps Pipeline Deployment for Competitive Business: The Winning Formula

We always hear about how important it is to be competitive and stand out in the market. But as an entrepreneur, how would you truly set your business apart? Is there any way to do...

React 18 Vs React 19: Key Differences To Know For 2024
React 18 Vs React 19: Key Differences To Know For 2024

Ever wondered how a simple technology can spark a revolution in the IT business? Just look at React.js - a leading Front-end JS library released in 2013, has made it possible. Praised for its seamless features, React.js has altered the way of bespoke app development with its latest versions released periodically. React.js is known for building interactive user interfaces and has been evolving rapidly to meet the demands of modern web development. Thus, businesses lean to hire dedicated React.js developers for their projects. React.js 19 is the latest version released and people are loving its amazing features impelling them for its adoption.