Saturday, May 13, 2023

Explain Unit of Work pattern

The Unit of Work pattern is a software design pattern that provides a way to manage transactions and coordinate the work of multiple repositories in an application. It helps maintain data consistency and integrity by ensuring that multiple operations are treated as a single unit of work and are either all committed or all rolled back.

The main purpose of the Unit of Work pattern is to abstract the underlying data access code and provide a high-level interface for managing transactions and coordinating changes to multiple entities. It ensures that all changes made within a unit of work are tracked and persisted consistently.

Here's a basic example of the Unit of Work pattern:

public interface IUnitOfWork : IDisposable
{
    void BeginTransaction();
    void Commit();
    void Rollback();
    void SaveChanges();
    IRepository<TEntity> GetRepository<TEntity>() where TEntity : class;
}

public class UnitOfWork : IUnitOfWork
{
    private readonly DbContext _context;
    private readonly Dictionary<Type, object> _repositories;
    private DbContextTransaction _transaction;

    public UnitOfWork(DbContext context)
    {
        _context = context;
        _repositories = new Dictionary<Type, object>();
    }

    public void BeginTransaction()
    {
        _transaction = _context.Database.BeginTransaction();
    }

    public void Commit()
    {
        _transaction.Commit();
        _transaction = null;
    }

    public void Rollback()
    {
        _transaction.Rollback();
        _transaction = null;
    }

    public void SaveChanges()
    {

        _context.SaveChanges();
    }

    public IRepository<TEntity> GetRepository<TEntity>() where TEntity : class
    {
        if (_repositories.ContainsKey(typeof(TEntity)))
        {
            return (IRepository<TEntity>)_repositories[typeof(TEntity)];
        }

        var repository = new Repository<TEntity>(_context);
        _repositories.Add(typeof(TEntity), repository);
        return repository;
    }

    public void Dispose()
    {
        _transaction?.Dispose();
        _context.Dispose();
    }
}
  

In this example, the IUnitOfWork interface defines the methods for beginning a transaction, committing or rolling back the transaction, saving changes, and retrieving repositories. The UnitOfWork class implements this interface and provides the concrete implementation.

The UnitOfWork class maintains an instance of the database context (DbContext) and a dictionary of repositories. The repositories are created lazily and stored in the dictionary to ensure that the same repository instance is used throughout the unit of work.

By using the Unit of Work pattern, you can ensure that multiple operations across different repositories are treated as a single unit of work. This allows you to maintain data consistency, perform atomic commits or rollbacks, and simplify the management of transactions in your application.

No comments:

Post a Comment