Repository Design Pattern In .NET CORE WEB API

In this article, I am going to explain how to structure your project in a repository design pattern.

Introduction

 
The main advantages of using design pattern are to keep the modules loosely coupled and to help developers address change requests with minimal changes to the code. Also, the modules can be reusable in multiple projects, which speeds up development. There are many design patterns, and one advantage of using the repository design pattern is to keep the data access logic centralized.
 
Initially, I struggled to understand both why we need AutoMapper and how to configure dependency injections in .NET CORE. But I received help from a senior architect, so now I am able to understand the complete data flow. I know there are many articles on this topic, but they may not answer all your questions and requirements.
 
In this article, I'm going to explain the data flow so that you can understand it as well.

Repository Design Pattern In .NET CORE WEB API

Step 1 - Create a New API Project in VS

In Visual Studio, click on File, go to New, and select the appropriate project template.

Repository Design Pattern In .NET CORE WEB API
 
Click on OK. This opens up a new dialog. Select API and uncheck “configure HTTPS” for now. Click on OK.

Repository Design Pattern In .NET CORE WEB API

It creates a project and structure that looks like this.

Repository Design Pattern In .NET CORE WEB API

Step 2 - Create a New Class Library Project for Data

Right click on your solution. Go to Add, and select New Project.

Repository Design Pattern In .NET CORE WEB API
 
Select the Class Library project and Click OK.

Repository Design Pattern In .NET CORE WEB API
 
Next, create a database in the SQL Server and create a test table with a few columns as shown below.

Repository Design Pattern In .NET CORE WEB API

How to Connect Your SQL DB With Your .NET Core Application

Next we need to scaffold the SQL database by running a command.

Click on Tools, go to NuGet Package Manager, and select Package Manager Console.

Run the below command. Before running this command make sure that you’ve selected “Data Class Library Project” in the top dropdown of the package manager console.
  1. Scaffold-DbContext "Server=tcp:xxxxxserver.database.windows.net;Database=xxxx_dev;User Id=xxxxxxx;Password=xxxxxx"  Microsoft.EntityFrameworkCore.SqlServer -Context CsharpCornerContext -Force  
This will create your DBContext class and all the other table objects. Open the created context file and remove the constructors without parameters with the OnConfiguring method.

Repository Design Pattern In .NET CORE WEB API

Repository Design Pattern In .NET CORE WEB API

Next you need to create a DBContextPool in your API Project.

Go to your API Project and open the startup.cs file. Modify the ConfigureService method and create the DBContextPool like below.
  1. services.AddEntityFrameworkSqlServer();  
  2.            services.AddDbContextPool<CsharoCornerContext>((serviceProvider, options) => { options.UseSqlServer(Configuration.GetConnectionString("connStr")); });  
The connection string is added in appsettings.json and referenced here.

Note
If you get any error with UseSqlServer, then import manually using Microsoft.EntityFrameworkCore.
 
Step 3 - Create a New Class Library Project for the Repository

Follow the above steps to create a class library project.

Next, create a DBHelper Class (optional). Create a repository class named “Common Repository.”

Repository Design Pattern In .NET CORE WEB API
 
Next, inject your DBContext (and DBHelper if you configured it) into your repository as shown below.
  1. class CommonRepository : ICommonRepository  
  2.  {  
  3.      private readonly IDBHelper dBHelper;  
  4.      private CsharoCornerContext csharoCornerContext;  
  5.   
  6.      public CommonRepository(IDBHelper dBHelper, CsharoCornerContext csharoCornerContext)  
  7.      {  
  8.          this.csharoCornerContext = csharoCornerContext;  
  9.          this.dBHelper = dBHelper;  
  10.      }  
  11.  }  
Create a common controller in your API Project.
  1. [Route("api/[controller]")]  
  2.   [ApiController]  
  3.   public class CommonController : ControllerBase  
  4.   {  
  5.   }  
Inject your common repository into a common controller as shown below.
  1. [Route("api/[controller]")]  
  2.     [ApiController]  
  3.     public class CommonController : ControllerBase  
  4.     {  
  5.         private ICommonRepository commonRepository;  
  6.         public CommonController(ICommonRepository commonRepository)  
  7.         {  
  8.             this.commonRepository = commonRepository;  
  9.         }  
  10.     }  
Next we need to configure the repository in the startup.cs file of the API Project.

Add the below two lines in your ConfigurationService method.
  1. services.AddScoped<ICommonRepository, CommonRepository>();  
  2.             services.AddScoped<IDBHelper, DBHelper>();  
Step 4 - Create a Class Library Project for Models, DTO, and ResultSet

Follow the same steps as above to create your class library project.

Models are used to get data from users, which is the payload for an API.
DTO is used to transfer data from one layer to another layer (from the controller to the repository).
ResultSet is used to perform DB operations.

After creating a separate class library project for each one of the above, the structure looks like below.

Repository Design Pattern In .NET CORE WEB API
  
Step 5 - Create a Class Library Project for AutoMapper

Follow the same steps as above to create a class library project.

We need to install AutoMapper, which is a simple little library built to solve a deceptively complex problem -- getting rid of code that has mapped one object to another.
  1. PM> Install-Package AutoMapper  
Right click on Project and create a mapping class and inherit profile using AutoMapper. The code looks like below.
  1. using AutoMapper;  
  2. using System;  
  3. using System.Collections.Generic;  
  4. using System.Text;  
  5.   
  6. namespace CsharpCornerDemo.Mapping  
  7. {  
  8.     public class Mappers : Profile  
  9.     {  
  10.         public Mappers()  
  11.         {  
  12.   
  13.         }  
  14.     }  
  15. }  
Next, we need to configure AutoMapper in the API Project and create a singleton instance of it.

Open Startup.cs file and modify the ConfigurationService method like below.

Note: You need to install AutoMapper.
  1. var mappingConfiguration = new MapperConfiguration(config => config.AddProfile(new Mappers()));  
  2.             IMapper mapper = mappingConfiguration.CreateMapper();  
  3.             services.AddSingleton(mapper); 
Step 6 - Write an API to Connect All Layers

Let’s write an API to get data fromTesttbl.

First, create a ResultSet and DTO for Testtbl.

Repository Design Pattern In .NET CORE WEB API
 
Inject mappers in the repository and the controller. It looks like this.
  1. public class CommonRepository : ICommonRepository  
  2.     {  
  3.         private readonly IDBHelper dBHelper;  
  4.         private CsharoCornerContext csharoCornerContext;  
  5.         private IMapper mapper;  
  6.   
  7.         public CommonRepository(IDBHelper dBHelper, CsharoCornerContext csharoCornerContext, IMapper mapper)  
  8.         {  
  9.             this.csharoCornerContext = csharoCornerContext;  
  10.             this.dBHelper = dBHelper;  
  11.             this.mapper = mapper;  
  12.         }  
  13.     }  
Create a method to get the test data in a common repository like below, calling Stored Procedure.
  1. public IEnumerable<TestDTO> GetTestData()  
  2.       {  
  3.           var result = csharoCornerContext.Query<TestResultSet>().FromSql("dbo.TestData").ToList();  
  4.           return mapper.Map<List<TestDTO>>(result);  
  5.       }  
Create an API in the common controller and call the GetTestData method.
  1. [HttpGet("test")]  
  2.        [ProducesResponseType(200)]  
  3.        [ProducesResponseType(400)]  
  4.        public async Task<IActionResult> GetTestData()  
  5.        {  
  6.            try  
  7.            {  
  8.   
  9.                var test = await Task.FromResult(commonRepository.GetTestData());  
  10.                return Ok(test);  
  11.            }  
  12.            catch  
  13.            {  
  14.                return BadRequest("Could not fetch test data");  
  15.            }  
  16.        }  
Also, we need to add mappers.
  1. public class Mappers : Profile  
  2.   {  
  3.       public Mappers()  
  4.       {  
  5.           CreateMap<TestResultSet, TestDTO>();  
  6.       }  
  7.   }  
Let's test the API.

Repository Design Pattern In .NET CORE WEB API
 

Summary


In this article, we discussed how to use repository design pattern in a .NET CORE Web API, as well as how to use AutoMapper. I hope this article was useful, and that you now have a better understanding of the data flow.