What is Repository Design Pattern
Repository is just a class that is associated with some entity and it manages all possible actions of that entity including CRUD operation.
For example we have a Student entity then , a Student repository will contain these basic methods e.g. Add , Update , Get , GetById and Delete
The Repository Pattern is a layer that mediates between the domain and the data access layers. Itโs like a buffer that controls how data is accessed and manipulated
Then we inject our repositories in services/handlers and use them [ But not all the time ]
How to implement it in .NET Core
Letโs suppose we are dealing with Student entity. So its repository would look like this.
public interface IStudentRepositroy
{
public bool Delete(int id);
public bool Add (StudentDTO student);
public bool Update (StudentDTO student);
public Task<StudentDTO> GetById(int id);
public Task<List<StudentDTO>> Get(int page, int pageSize);
}
With implementation:
So the main thing to note here is that only repositories are responsible to talk with database.
Donโt forget to register dependency of your repository in your Program.cs
We are creating a layer of abstraction here , handler has no idea how those method are working and what database is being used behind the seen.
It is common practice to use generic repositories where we have to deal with multiple CRUD operations for multiple entities
Suppose we are making a Land System where we have to deal with States, Cities ,Districts and next in the hierarchy , then generic repository would be perfect solution for that problem.
Dependency injection of open generics is little bit different , check this from a previous post :
Unit of Work
I have above mentioned that we can inject our repositories in constructor of our handler or service and use it . This is fine just for couple of repos what if those increases then this is not good approach to keep injecting every new repo in constructor.
That is where Unit of Work pattern comes into an action. We put all of our repositories in UnitOfWok and it is responsible for pushing changes in database as well. That is how it looks like :
UnitOfWork would be like this :
Now instead of injecting repositories we would inject our IUnitOfWork , this approach has following benefits
More clean
It saves use from multiple injections in our desired class/services/handlers
It saves us from data leakage if multiple repositories objects have different instance of DbContext
Now we can use IUnitOfWork in our service/handler/controller like this
Controller
Pros and Cons
These are few benefits of using this pattern
- ๐ฆ๐ฒ๐ฝ๐ฎ๐ฟ๐ฎ๐๐ถ๐ผ๐ป ๐ผ๐ณ ๐ฐ๐ผ๐ป๐ฐ๐ฒ๐ฟ๐ป๐: The repository pattern separates the logic that retrieves the data and maps it to the entity model.
- ๐ฅ๐ฒ๐ฑ๐๐ฐ๐ฒ๐ ๐ฐ๐ผ๐ฑ๐ฒ ๐ฑ๐๐ฝ๐น๐ถ๐ฐ๐ฎ๐๐ถ๐ผ๐ป: Your data access logic can be reused across multiple projects.
- ๐จ๐ป๐ถ๐ ๐ง๐ฒ๐๐๐ถ๐ป๐ด: It becomes a breeze as the data access logic is decoupled from the business services.
- ๐๐ถ๐ฑ๐ฒ๐ ๐ฆ๐ค๐: Hides complex SQL or query language details, offering a cleaner API for accessing data.
But no hero is without its flaws:
- ๐ข๐๐ฒ๐ฟ๐ต๐ฒ๐ฎ๐ฑ: Implementing the repository pattern introduces a new layer, which can be an overhead for small projects.
- ๐๐ฒ๐ป๐ฒ๐ฟ๐ถ๐ฐ ๐ฅ๐ฒ๐ฝ๐ผ๐๐ถ๐๐ผ๐ฟ๐ถ๐ฒ๐: They can limit your ability to perform complex database operations and can lead to performance penalties.
- ๐๐ฒ๐ฎ๐ฟ๐ป๐ถ๐ป๐ด ๐๐๐ฟ๐๐ฒ: It takes time to understand and implement the repository pattern correctly
Covering each aspect of this topic in less than 5 minutes was difficult , I have tried to give basic overview that how it looks like using a repository pattern. For more detailed read visit Microsoft Docs
Whenever you're ready, there are 3 ways I can help you:
- Subscribe to my youtube channel : For in-depth tutorials, coding tips, and industry insights.
- Promote yourself to 9,000+ subscribers : By sponsoring this newsletter
- Patreon community : Get access to all of my blogs and articles at one place