Unit of Work

Mantiene una lista de operaciones afectadas por una transacción de negocio y coordina su escritura.

Contexto

Una operación de negocio modifica varios agregados (Order, Inventory, Audit). Quieres confirmar TODO o nada.

Problema

Sin coordinación, puedes guardar el pedido pero fallar al descontar stock.

Solución

Un UnitOfWork agrupa las operaciones y las confirma con SaveChanges() dentro de una transacción única.

#Ejemplo en C#

public interface IUnitOfWork : IAsyncDisposable
{
    IOrderRepository Orders { get; }
    IInventoryRepository Inventory { get; }
    Task<int> SaveChangesAsync(CancellationToken ct = default);
}

public class EfUnitOfWork : IUnitOfWork
{
    private readonly AppDbContext _db;
    public EfUnitOfWork(AppDbContext db, IOrderRepository o, IInventoryRepository i)
    { _db = db; Orders = o; Inventory = i; }

    public IOrderRepository Orders { get; }
    public IInventoryRepository Inventory { get; }

    public Task<int> SaveChangesAsync(CancellationToken ct = default) => _db.SaveChangesAsync(ct);
    public ValueTask DisposeAsync() => _db.DisposeAsync();
}

// Uso
await using var uow = factory.Create();
uow.Orders.Add(order);
uow.Inventory.Reserve(order.Items);
await uow.SaveChangesAsync();

En EF Core, DbContext ya es un Unit of Work. Crear otro encima suele ser redundante.

Cuándo NO aplicarlo
  • Si tu ORM ya implementa Unit of Work (EF, NHibernate).
  • Si las operaciones cruzan procesos (ahí necesitas Saga / Outbox).

#extra #persistence #transaction