Repository and Unit of Work Pattern - Details of the Unit of Work Pattern

Learn how to group operations into a single transaction with the Unit of Work pattern, complete with a practical implementation.

Summary

This article is part of a series covering the Repository and Unit of Work patterns:

Unit of Work Pattern: Managing Transactions

The Unit of Work Pattern is designed to group multiple operations into a single coherent transaction. It ensures that all modifications are either successfully executed or rolled back in case of failure.

Unit of Work Interface Example

public interface IUnitOfWork : IDisposable
{
    IRepository<T> Repository<T>() where T : class;
    Task<int> SaveChangesAsync();
}

Unit of Work Implementation

Here is a basic implementation:

public class UnitOfWork : IUnitOfWork
{
    private readonly DbContext _context;
    private readonly Dictionary<string, object> _repositories = new();

    public UnitOfWork(DbContext context)
    {
        _context = context;
    }

    public IRepository<T> Repository<T>() where T : class
    {
        var typeName = typeof(T).Name;

        if (!_repositories.ContainsKey(typeName))
        {
            var repositoryInstance = new Repository<T>(_context);
            _repositories[typeName] = repositoryInstance;
        }

        return (IRepository<T>)_repositories[typeName];
    }

    public async Task<int> SaveChangesAsync() => await _context.SaveChangesAsync();

    public void Dispose() => _context.Dispose();
}

This pattern isolates transaction management and coordinates repositories within a single unit.

A suivre : Compatibility and Limitations with Microservices