Repository Pattern in ASP.NET Core Web API example 2026 guide

Repository Pattern in ASP.NET Core Web API with Example – 2026 Guide

Problems Without Repository Pattern

What is Repository Pattern?

Prerequisites / Setup

Step-by-Step Implementation of Repository Pattern in ASP.NET Core Web API

Step 1: Create a New ASP.NET Core Web API Project

Step 2: Add Project Folders

Step 3: Install Required NuGet Packages

Step 4: Create the Product Entity

namespace MyApi.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public int Stock { get; set; }
    }
}

Step 5: Create AppDbContext

using Microsoft.EntityFrameworkCore;
using MyApi.Models;

namespace MyApi.Data
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) 
        {       
        }

        public DbSet<Product> Products { get; set; }
    }
}

Step 6: Create the Repository Interface

using MyApi.Models;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace MyApi.Repositories
{
    public interface IProductRepository
    {
        Task<IEnumerable<Product>> GetAllAsync();
        Task<Product> GetByIdAsync(int id);
        Task AddAsync(Product product);
        Task UpdateAsync(Product product);
        Task DeleteAsync(int id);
    }
}

Step 7: Implement the Repository

using Microsoft.EntityFrameworkCore;
using MyApi.Data;
using MyApi.Models;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace MyApi.Repositories
{
    public class ProductRepository : IProductRepository
    {
        private readonly AppDbContext _context;

        public ProductRepository(AppDbContext context)
        {
            _context = context;
        }

        public async Task<IEnumerable<Product>> GetAllAsync()
        {
            return await _context.Products.ToListAsync();
        }

        public async Task<Product> GetByIdAsync(int id)
        {
            return await _context.Products.AsNoTracking().
            SingleOrDefaultAsync(p => p.Id ==   id);
         }

        public async Task AddAsync(Product product)
        {
            _context.Products.Add(product);
            await _context.SaveChangesAsync();
        }

        public async Task UpdateAsync(Product product)
        {
            _context.Products.Update(product);
            await _context.SaveChangesAsync();
        }

        public async Task DeleteAsync(int id)
        {
            var product = await _context.Products.FindAsync(id);
            if (product != null)
            {
                _context.Products.Remove(product);
                await _context.SaveChangesAsync();
            }
        }
    }
}

Step 8: Configure Dependency Injection

using Microsoft.EntityFrameworkCore;
using MyApi.Data;
using MyApi.Repositories;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container
builder.Services.AddControllers();

// Configure DbContext
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

// Register repository
builder.Services.AddScoped<IProductRepository, ProductRepository>();

// Add Swagger services
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Enable Swagger UI in Development
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();

app.MapControllers();

app.Run();

Step 9: Database Setup

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=MyApiDb;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}
Add-Migration InitialCreate
Update-Database

Step 10: Create Products Controller

using Microsoft.AspNetCore.Mvc;
using MyApi.Models;
using MyApi.Repositories;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace MyApi.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ProductsController : ControllerBase
    {
        private readonly IProductRepository _repository;

        public ProductsController(IProductRepository repository)
        {
            _repository = repository;
        }

        [HttpGet]
        public async Task<IEnumerable<Product>> GetAll() => await _repository.GetAllAsync();

        [HttpGet("{id}")]
        public async Task<ActionResult<Product>> GetById(int id)
        {
            var product = await _repository.GetByIdAsync(id);
            if (product == null) return NotFound();
            return product;
        }

        [HttpPost]
        public async Task<ActionResult> Create(Product product)
        {
            await _repository.AddAsync(product);
            return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
        }

        [HttpPut("{id}")]
        public async Task<ActionResult> Update(int id, Product product)
        {
            if (id != product.Id) return BadRequest();
            await _repository.UpdateAsync(product);
            return NoContent();
        }

        [HttpDelete("{id}")]
        public async Task<ActionResult> Delete(int id)
        {
            await _repository.DeleteAsync(id);
            return NoContent();
        }
    }
}

Step 11: Test Your API

https://localhost:{port}/swagger
Screenshot of Repository pattern Swagger UI listing GET, POST, PUT, DELETE endpoints for Products API in ASP.NET Core Web API.
Swagger UI screenshot of Repository Pattern with expanded GET endpoints for Products API, showing example requests and responses.

Why Use Repository Pattern in ASP.NET Core

1. Keeps your code clean and organized

2. Makes testing much easier

3. Reduces duplicated code

4. Flexible for future changes

5. Better for large projects and teams

In short:

Conclusion

Frequently Asked Questions (FAQ)

1. What is the Repository Pattern in ASP.NET Core?

2. Why should I use the Repository Pattern?

3. Do I need to use it in every project?

4. Does Entity Framework Core already work like a repository?

5. What is the difference between Repository and DbContext?

6. Can I use Repository Pattern with Unit of Work?

7. Does Repository Pattern improve performance?

Related Articles

🚀 Subscribe for Tech Updates

📧

👤

We respect your privacy. Unsubscribe anytime.

Leave a Comment

Your email address will not be published. Required fields are marked *