Tool for HR, Hiring Managers, and the Leadership Team

Repository Pattern

The Repository Pattern is one of the most commonly asked design pattern interview questions, especially for .NET / backend developers.

What is Repository Pattern?

Repository Pattern is used to separate data access logic from business logic.

Instead of directly writing database code inside services/controllers, you create a Repository layer that handles CRUD operations.

Without Repository Pattern

Controller → Database directly ❌

With Repository Pattern

Controller → Service → Repository → Database ✅

This makes the application:

  • Clean

  • Maintainable

  • Testable

  • Scalable

Real World Example

Think of Amazon

You don't directly go to the warehouse.

You interact with:

Amazon App → Service → Warehouse

Here:

  • Warehouse = Database

  • Service = Business logic

  • Repository = Warehouse manager

Why Repository Pattern?

Interviewers love this question.

Advantages

✅ Separation of concerns
✅ Easy to test (Mock repository)
✅ Reusable code
✅ Maintainable
✅ Clean architecture

Example in C#

Let's say we have a User table.

Step 1 — Create Model

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Step 2 — Create Repository Interface

This defines what operations are allowed.

public interface IUserRepository
{
    IEnumerable<User> GetAll();
    User GetById(int id);
    void Add(User user);
    void Update(User user);
    void Delete(int id);
}

Step 3 — Implement Repository

Using Entity Framework Core

public class UserRepository : IUserRepository
{
    private readonly AppDbContext _context;

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

    public IEnumerable<User> GetAll()
    {
        return _context.Users.ToList();
    }

    public User GetById(int id)
    {
        return _context.Users.Find(id);
    }

    public void Add(User user)
    {
        _context.Users.Add(user);
        _context.SaveChanges();
    }

    public void Update(User user)
    {
        _context.Users.Update(user);
        _context.SaveChanges();
    }

    public void Delete(int id)
    {
        var user = _context.Users.Find(id);
        _context.Users.Remove(user);
        _context.SaveChanges();
    }
}

Step 4 — Use Repository in Service

public class UserService
{
    private readonly IUserRepository _repository;

    public UserService(IUserRepository repository)
    {
        _repository = repository;
    }

    public IEnumerable<User> GetUsers()
    {
        return _repository.GetAll();
    }
}

Step 5 — Register in Dependency Injection

In ASP.NET Core

builder.Services.AddScoped<IUserRepository, UserRepository>();

Controller Example

[ApiController]
[Route("api/users")]
public class UsersController : ControllerBase
{
    private readonly UserService _service;

    public UsersController(UserService service)
    {
        _service = service;
    }

    [HttpGet]
    public IActionResult Get()
    {
        return Ok(_service.GetUsers());
    }
}

Repository Pattern Flow

Controller
    ↓
Service
    ↓
Repository
    ↓
Database

Generic Repository Pattern (Very Popular Interview Question)

Instead of creating repository for every entity:

  • UserRepository

  • ProductRepository

  • OrderRepository

Create Generic Repository

Generic Repository Interface

public interface IRepository<T>
{
    IEnumerable<T> GetAll();
    T GetById(int id);
    void Add(T entity);
    void Update(T entity);
    void Delete(int id);
}

Generic Repository Implementation

public class Repository<T> : IRepository<T> where T : class
{
    private readonly DbContext _context;
    private readonly DbSet<T> _dbSet;

    public Repository(DbContext context)
    {
        _context = context;
        _dbSet = context.Set<T>();
    }

    public IEnumerable<T> GetAll()
    {
        return _dbSet.ToList();
    }

    public T GetById(int id)
    {
        return _dbSet.Find(id);
    }

    public void Add(T entity)
    {
        _dbSet.Add(entity);
        _context.SaveChanges();
    }

    public void Update(T entity)
    {
        _dbSet.Update(entity);
        _context.SaveChanges();
    }

    public void Delete(int id)
    {
        var entity = _dbSet.Find(id);
        _dbSet.Remove(entity);
        _context.SaveChanges();
    }
}

When Should You Use Repository Pattern?

Use when:

✅ Using Database
✅ Large applications
✅ Clean architecture
✅ Unit testing needed
✅ Multiple data sources

When NOT to Use

Sometimes Repository Pattern is unnecessary if using:

  • Simple CRUD app

  • Small project

  • Already using Entity Framework (EF already behaves like repository)

This is advanced interview discussion point ⭐

Interview Questions (Very Important)

1. What is Repository Pattern?

Repository Pattern separates data access logic from business logic.

2. What is Generic Repository?

A repository that works for all entities using generics.

3. Repository vs Service Pattern?

Repository → Data access
Service → Business logic

4. Repository vs Unit of Work?

Repository → Handles one entity
Unit of Work → Handles transactions across multiple repositories

Interview Tip

Best answer (short version):

Repository Pattern is used to separate data access logic from business logic. It improves maintainability, testability, and follows clean architecture principles.