Design Patterns Mastery

Repository & Unit of Work (The EF Core Standard)

1 Views Updated 5/4/2026

Repository & Unit of Work

In Enterprise .NET, the Repository Pattern abstracts data access logic behind an interface, while the Unit of Work ensures that multiple repository operations use a single database transaction. Together, they create a clean layer of separation between your Business Logic and your Database Technology.

1. Repository: The "In-Memory Collection" Illusion

A repository should make the caller feel like they are interacting with a simple List<T>, hidden the complexities of SQL, IQueryable, and DB contexts.

public interface IRepository<T> 
{
    Task<IEnumerable<T>> GetAll();
    void Add(T entity);
}

2. Unit of Work: Atomic Transactions

If you create a 'User' and its 'Settings' in two separate repositories, you want them both to succeed or both to fail. The Unit of Work holds the _context.SaveChangesAsync() method, ensuring atomicity.

public class UnitOfWork : IUnitOfWork 
{
    private readonly AppDbContext _db;
    public IUserRepository Users { get; }
    
    public async Task Complete() => await _db.SaveChangesAsync();
}

4. Interview Mastery

Q: "Is it redundant to use the Repository pattern with Entity Framework Core, since DbContext is already a Unit of Work?"

Architect Answer: "Technically, yes. `DbSet` is a Generic Repository and `DbContext` is a Unit of Work. However, we still use repositories to **Decouple** our business logic from EF-specific code. By using a custom repository, we can prevent 'Leaky Abstractions' like exposing `IQueryable` (which allows logic to bleed into the UI layer) and we make our business services much easier to Unit Test without needing a complex InMemory database setup."

Design Patterns Mastery
1. Introduction to Design Patterns
Introduction to GoF Patterns: Why patterns matter? SOLID Principles: The foundation of all patterns DRY, KISS, and YAGNI (Architectural Philosophy)
2. Creational Patterns
Singleton Pattern: Thread-safety & Captive Dependencies Factory Method: Abstracting complex object creation Abstract Factory: Creating families of related objects Builder Pattern: Constructing complex fluents Prototype Pattern: Cloning high-cost objects
3. Structural Patterns
Adapter Pattern: Bridging incompatible interfaces Bridge Pattern: Decoupling abstraction from implementation Composite Pattern: Managing tree structures & hierarchies Decorator Pattern: Enhancing behavior without inheritance Facade Pattern: Simplifying complex library subsystems Flyweight Pattern: Drastically reducing memory footprint Proxy Pattern: Interception, Lazy-Loading, and Security
4. Behavioral Patterns
Chain of Responsibility: Middleware & Pipeline Architecture Command Pattern: Implementing Undo/Redo & Queueing Interpreter Pattern: Building domain-specific languages Iterator Pattern: Unified traversal of collections Mediator Pattern: Decoupling components with MediatR Memento Pattern: Capturing and restoring object state Observer Pattern: Pub/Sub & Event-driven architecture State Pattern: Managing complex object lifecycles Strategy Pattern: Swappable algorithms at runtime Template Method: Defining skeleton algorithms Visitor Pattern: Separating operations from data structures
5. Modern Enterprise & Cloud Patterns
Repository & Unit of Work (The EF Core Standard) CQRS Pattern (Command Query Responsibility Segregation) Circuit Breaker & Retry Patterns (Resilience with Polly) Dependency Injection Pattern (The Modern King)