Is the Repository Pattern Dead?
Introduction
The repository pattern has been a cornerstone of enterprise .NET architecture for years. It promised clean separation between business logic and data access, testability, and maintainability. But with modern ORMs like Entity Framework Core, and new design trends like CQRS, many developers are asking:
Is the repository pattern still relevant, or is it finally dead?
- What Is the Repository Pattern?
The Repository pattern is a well-known design pattern that aims to separate the logic that retrieves data from the business logic that acts on the data.
"A Repository mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects."— Martin Fowler, Patterns of Enterprise Application Architecture
In practice, this means using a class that acts like an in-memory collection of domain objects — hiding whether the data comes from SQL, a web service, or somewhere else:
public interface ICustomerRepository
{
Task<Customer> GetByIdAsync(Guid id);
Task AddAsync(Customer customer);
}
Originally, this was valuable when ORMs weren’t mature and data access logic was verbose and database-specific.
- Why People Say It’s Dead
✅ EF Core Is Already a Repository
DbContext and DbSet provide the core functionality repositories offer: querying, adding, removing, and tracking entities.
❌ Boilerplate Hell
Most custom repositories end up duplicating what EF already provides:
public Task<Customer> GetByIdAsync(Guid id) => _context.Customers.FindAsync(id);
...which is not value-added abstraction.
Over-Abstraction Hurts
You lose direct access to EF Core's powerful features like:
.Include() for eager loading
.AsNoTracking() for read-only queries
Raw SQL with .FromSqlRaw()
However, patterns like Ardalis.Specification allow you to retain advanced EF Core features such as eager loading via .Include(), while still keeping your repository clean and decoupled. Specifications can express query logic clearly, including filters, includes, and sorting.
“Switching databases” is not a strong reason anymore
A common argument for using repositories is to make it easier to swap out databases (e.g., from SQL Server to PostgreSQL). But with Entity Framework Core, your application already depends on an abstraction — EF itself. Changing providers typically involves minimal changes to the DbContext configuration and nothing in your business logic. Adding another repository layer just to enable “swap-ability” is usually over-engineering.
- When the Repository Pattern Still Makes Sense
Despite the criticism, there are valid scenarios where repositories shine:
Domain-Driven Design (DDD) with rich aggregates and business rules
Abstracting external data sources (SQL + API + NoSQL)
Clear boundaries in microservices
NuGet/Repo Suggestions:
Ardalis.Specification: A clean implementation of the Specification Pattern that works great with EF Core.
Ardalis.CleanArchitecture: A full solution template with proper use of repositories and separation of concerns.
Refit: For when your "repository" is actually calling an external API.
EFCore.BulkExtensions: If you do stay close to DbContext, this helps with batch operations and performance.
- Modern Alternatives
Rather than force-fitting repositories, modern .NET developers are adopting:
CQRS + MediatR: Commands and queries are separated cleanly.
MediatR: Lightweight in-process messaging.
Query Object Pattern: Encapsulates complex queries into reusable classes.
Minimal APIs + DbContext injection (in .NET 6+): Simple, fast, and testable.
- Pragmatic Verdict
So, is the repository pattern dead? Not quite.
It's just no longer mandatory.
Use it when it adds value — such as enforcing boundaries, abstracting external sources, or aligning with your team's architecture. But don’t blindly wrap EF Core unless there’s a real reason.
Conclusion
The repository pattern isn’t dead — it’s evolved. In modern .NET, we have better tools, smarter defaults, and community-tested patterns like Ardalis.Specification that give you structure only when you need it.
Choose the right tool for your context. That’s real architecture.
References
Martin Fowler – Repository Pattern
Steve Smith – Ardalis.Specification GitHub
Steve Smith – Clean Architecture Template
Jeremy Bogard – MediatR GitHub
EFCore Bulk Extensions – GitHub Repository
Refit – GitHub Repository