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
Now, I will demonstrate how to create a entity framework repository example. 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).
Install NuGet packages (Code.RepositoryPattern.EntityFramework)
Microsoft.EntityFrameworkCore.
Microsoft.EntityFrameworkCore.Design.
Microsoft.EntityFrameworkCore.SqlServer.
Implementing a Repository Pattern in ASP.NET Core
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 Repository Example
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: Add, Get, GetAll, 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. Well, we 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 (Get, GetAll, Add, Remove) 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:
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.
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
You can read the original post from Medium.com
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.