Back to results for “Dependency injection”
C# › Design Patterns in C#

How does the Repository pattern abstract data access, and what interface typically defines its contract?

Intermediate

Answer

The Repository pattern defines an interface (like IRepository<T>) exposing domain-focused CRUD operations, hiding the underlying data access technology (Entity Framework, raw SQL, an external API) behind that abstraction — letting business logic depend on the abstraction rather than a specific persistence mechanism.
public interface IRepository<T> {
  Task<T?> GetByIdAsync(int id);
  Task<IEnumerable<T>> GetAllAsync();
  Task AddAsync(T entity);
}
public class UserRepository : IRepository<User> {
  // implementation using EF Core, backed by AppDbContext
}
Real-world example Decoupling business logic from Entity Framework specifics, making it possible to swap the data layer or mock it easily in tests.

Common follow-ups: Is the Repository pattern still considered necessary on top of Entity Framework Core's DbSet<T>, which already provides similar abstraction?