Aller au contenu

Unit of Work Pattern

De Banane Atomic


Description

Used to manage transactions and ensure data consistency across multiple operations.
Key Components and Benefits:

  • Transaction Management: ensures that multiple database operations are treated as a single transaction. This means that either all operations succeed or none of them do, maintaining data integrity and consistency.
  • Repository Coordination: It coordinates the work of multiple repositories by using a shared database context. This allows for efficient management of complex transactions involving multiple entities.
  • Scalability: As the number of repositories increases, it helps manage complexity by ensuring all operations participate in the same transaction.
  • Persistence Ignorance: It abstracts the underlying data access technology, allowing developers to switch between different data access frameworks like EF Core, Dapper, or ADO.NET without affecting the business logic.

Implementation

UnitOfWork.cs
public class UnitOfWork : IUnitOfWork, IDisposable
{
    private readonly MyAppContext context;
    private IDbTransaction? transaction;

    public UnitOfWork(MyDbContext context)
    {
        this.context = context;
    }

    public async Task BeginTransactionAsync()
    {
        if (transaction != null)
        {
            throw new InvalidOperationException("Transaction already started.");
        }
        transaction = await context.Database.BeginTransactionAsync();
    }

    public async Task CommitAsync()
    {
        if (transaction == null)
        {
            throw new InvalidOperationException("No transaction started.");
        }
        await context.SaveChangesAsync();
        await transaction.CommitAsync();
        transaction = null;
    }

    public async Task RollbackAsync()
    {
        if (transaction == null)
        {
            throw new InvalidOperationException("No transaction started.");
        }
        await transaction.RollbackAsync();
        transaction = null;
    }

    public void Dispose()
    {
        if (transaction != null)
        {
            transaction.Dispose();
        }
    }
}

public interface IUnitOfWork
{
    Task BeginTransactionAsync();
    Task CommitAsync();
    Task RollbackAsync();
}