How to Implement Repository Pattern & .NET Core

How to Implement Repository Pattern & .NET Core

What is a Repository?

According to Martin Fowler’s definition:

“A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection.

Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.”

Benefits

  • Minimizes duplicate query and database logic.
  • Decouples your implementation from persistence frameworks or solutions.
  • Provides a flexible architecture.
  • Code centralization.
  • Avoids code redundancy.

Implementation

Open Visual Studio (I am using Visual Studio 2019) and create the following solution with these projects:

  • Code.RepositoryPattern.Api (ASP.NET Core Web Application, API).
  • Code.RepositoryPattern.EntityFramework (Class library .NET Core).
  • Code.RepositoryPattern.Model (Class library .NET Core).
  • Code.RepositoryPattern.Repository (Class library .NET Core).

Image 01: Solution

Install NuGet packages (Code.RepositoryPattern.EntityFramework)
Microsoft.EntityFrameworkCore.
Microsoft.EntityFrameworkCore.Design.
Microsoft.EntityFrameworkCore.SqlServer.

Image 02: NuGet Packages

Implementing a Repository Pattern

Adding a Model

We will add our first model class in Code.RepositoryPattern.Model

Adding IRepository

In this section, we will create our Repository contract in Code.RepositoryPattern.Repository. In this interface, we have four generic methods for four basic operations. Get by Id, Get All, Add a new item, and Remove an existing item.

Adding IBookRepository

So, we will add an interface with reference to IRepository. The main purpose of this interface is to have a strongly-typed contract with our model (Book).

Also, I have added two additional methods exclusively for Book domain.

Setting our Persistence component: Entity Framework

After installing EntityFrameworkCore NuGet packages, we are going to implement our data access component using the contracts created in previous steps.

First of all, we will create an abstract class named Repository with a generic type (TModel), it implements IRepository<TModel>. At this point, we have to implement the methods of IRepository contract: AddGetGetAll, and Remove. For that purpose, we will need a DbContext member.

We will add the DbContext class for our application. A DbSet for Book model was included as well.

Repository of Books

We have our generic contract (IRepository), our strongly-typed contract (IBookRepository), and the Repository class (Repository) which implements IRepository. Wellwe are going to implement the main goal of this post: a repository of books: BookRepository.

This class is typed and inherits from Repository<Book> in order to have the basic methods (GetGetAllAddRemove) defined in IBookRepository. Besides, we will implement GetBooks and GetBooksByCurrentYear methods, established in IBookRepository.

Now, let me show you the final structure of our Code.RepositoryPattern.EntityFramework project:

Image 03: Persistence layer with EntityFramework

Web API

Let’s go to Code.RepositoryPattern.Api project. In that one, we will add two classes:

ParentController: In this class, we define a base controller that will be prepared to support our models and repositories, using generic types in the class definition.

In the constructor, we will inject a dependency of the concrete repository.
In the rest of the class, we will have the HTTP methods implementation.

Well, we can add the BooksController. It inherits from ParentController, setting the types Book (Model) and BookRepository (Persistence class in EF).

Pay attention to those additional methods: ByCurrentYear and Get. Those are the methods exclusively created for Book domain.

Finally, this is the complete API project.

Image 04: API Projecy

So, if we want to use BooksController, we will be able to invoke these methods:

  • Get (Generic method from ParentController).
  • Add (Generic method from ParentController).
  • ByCurrentYear (Exclusive method for Books domain).
  • Get(int) (Exclusive method for Books domain, overloaded).

Finally, I will share with you all the Startup class of the API.

GitHub Repository

You can download this project from GitHub:
https://github.com/luisfernando-ch/RepositoryPattern

You can read the original post from Medium.com here: https://medium.com/@luisfernando_ch/repository-pattern-asp-net-core-ef-f12ee94b980e

About Luis Fernando Chavarriaga Cano

Luis Fernando Chavarriaga Cano is a staff software engineer at GAP. Before joining GAP in 2018, he was a software developer & architect with over 10 years of experience working on Microsoft technologies and .NET platforms. He is also a DevOps enthusiast.