Aller au contenu principal
Nicolas Cousin Tech SolutionsNicolas Cousin Tech Solutions
Module 2 of 6

Details of the Repository Pattern

Repository Pattern: Simplifying Data Access

The Repository Pattern creates an abstraction layer between the application and the data source. It centralises data access logic and avoids code duplication.

Generic Interface Example

Here is a simple implementation of a generic repository:

public interface IRepository<T> where T : class
{
    Task<T?> GetByIdAsync(int id);
    Task<IEnumerable<T>> GetAllAsync();
    Task AddAsync(T entity);
    void Update(T entity);
    void Delete(T entity);
}

Implementation with Entity Framework Core

A repository for a specific entity can derive from this interface:

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 async Task<T?> GetByIdAsync(int id) => await _dbSet.FindAsync(id);

    public async Task<IEnumerable<T>> GetAllAsync() => await _dbSet.ToListAsync();

    public async Task AddAsync(T entity) => await _dbSet.AddAsync(entity);

    public void Update(T entity) => _dbSet.Update(entity);

    public void Delete(T entity) => _dbSet.Remove(entity);
}

This pattern improves readability and reduces repetitive data access logic in the application.

Check your understanding

In the module's example, what does the GetByIdAsync method do?

Why use an IRepository<T> interface instead of a direct implementation?