The Repository Pattern is one of the most popular patterns to create an enterprise level application. It restricts us to work directly with the data in the application and creates new layers for database operations, business logic and the application’s UI. If an application does not follow the Repository Pattern, it may have the following problems:
- Duplicate database operations codes
- Need of UI to unit test database operations and business logic
- Need of External dependencies to unit test business logic
- Difficult to implement database caching, etc.
Using the Repository Pattern has many advantages:
- Your business logic can be unit tested without data access logic;
- The database access code can be reused;
- Your database access code is centrally managed so easy to implement any database access policies, like caching;
- It’s easy to implement domain logics;
- Your domain entities or business entities are strongly typed with annotations; and more.
On the internet, there are millions of articles written around Repository Pattern, but in this one we’re going to focus on how to implement it in an ASP.NET MVC Application. So let’s get started!
Let us start with creating the Project structure for the application. We are going to create four projects:
- Core Project
- Infrastructure Project
- Test Project
- MVC Project
Each project has its own purpose. You can probably guess by the projects’ names what they’ll contain: Core and Infrastructure projects are Class Libraries, Web project is a MVC project, and Test project is a Unit Test project. Eventually, the projects in the solution explorer will look as shown in the image below:
As we progress in this post, we will learn in detail about the purpose of each project, however, to start we can summarize the main objective of each project as the following:
So far our understanding for different projects is clear. Now let us go ahead and implement each project one by one. During the implementations, we will explore the responsibilities of each project in detail.
In the core project, we keep the entities and the repository interfaces or the database operation interfaces. The core project contains information about the domain entities and the database operations required on the domain entities. In an ideal scenario, the core project should not have any dependencies on external libraries. It must not have any business logic, database operation codes etc.
In short, the core project should contain:
- Domain entities
- Repository interfaces or database operations interfaces on domain entities
- Domain specific data annotations
The core project can NOT contain:
- Any external libraries for database operations
- Business logic
- Database operations code
While creating the domain entities, we also need to make a decision on the restrictions on the domain entities properties, for example:
- Whether a particular property is required or not. For instance, for a Product entity, the name of the product should be required property.
- Whether a value of a particular property is in given range or not. For instance, for a Product entity, the price property should be in given range.
- Whether the maximum length of a particular property should not be given value. For instance, for a Product entity, the name property value should be less than the maximum length.
here could be many such data annotations on the domain entities properties. There are two ways we can think about these data annotations:
- As part of the domain entities
- As part of the database operations logic
It is purely up to us how we see data annotations. If we consider them part of database operation then we can apply restrictions using database operation libraries API. We are going to use the Entity Framework for database operations in the Infrastructure project, so we can use Entity Framework Fluent API to annotate data.
If we consider them part of domain, then we can use System.ComponentModel.DataAnnotationslibrary to annotate the data. To use this, right click on the Core project’s Reference folder and click on Add Reference. From the Framework tab, selectSystem.ComponentModel.DataAnnotations and add to the project.