Skip to content

Repository and Unit of Work pattern implementation for Entity Framework Core.

License

Notifications You must be signed in to change notification settings

Daniel127/EF-Unit-Of-Work

Repository files navigation

Status

Quality Gate Lines of Code Bugs Coverage Maintainability Rating

Branch Build Deployment
master Build Build Status Nuget package
develop Build Build Status N/A

What is it?

Repository and Unit of Work pattern implementation for Entity Framework Core 3.

How to use?

Installation

Install the Nuget packages. Use Abstractions for logic layers and the other with insfrastructure layer or monolithic project.

dotnet add package QD.EntityFrameworkCore.UnitOfWork
dotnet add package QD.EntityFrameworkCore.UnitOfWork.Abstractions

Register Services

public class AppDbContext : DbContext, IDbContext
{
    public DbSet<Product> Products { get; set; }

    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }

    ...
    ...
}
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<AppDbContext>(builder =>
    {
        ...
    });

#region Register UnitOfWorks
    // Register a IUnitOfWork<AppDbContext>
    _services.AddUnitOfWork<AppDbContext>();
    // Register a IUnitOfWork<AppDbContext> and IUnitOfWork
    _services.AddUnitOfWork<AppDbContext>(onlyGeneric: false);
#endregion

    // Optional, register custom repositories
    _services.AddRepository<Product, ProductRepository>();
    _services.AddReadOnlyRepository<Product, ProductReadOnlyRepository>();
}

Use the services

public class FancyService : IFancyService
{
    private readonly IUnitOfWork<AppDbContext> _unitOfWork;

    public FancyService(IUnitOfWork<AppDbContext> unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    public void DoFancyThing()
    {
        var productsRepository = _unitOfWork.GetRepository<Product>();

        var products = productsRepository.GetAll();

        ...
        // Use inserts, updates, deletes.
        ...

        _unitOfWork.SaveChanges();
    }
}

Paged Collections (v2.0)

public void FancyFunction()
{
    // These are some examples

    // Array
    IPagedCollection<Product> page1 = _productsRepository.GetPagedArray(20, 0, product => product.Price > 500);
    IPagedCollection<Product> page2 = await _productsRepository.GetPagedArrayAsync(
        pageSize: 10,
        orderBy: query => query.OrderBy(product => product.Price).ThenBy(product => product.Name)
    );
    // Indexers
    var a = page1[1].Price;
    var b = ((PagedArray<Product>)page1)[2].Price;

    ...

    // List
    IPagedCollection<Product> page1 = _productsRepository.GetPagedList(20, 0, product => product.Price > 500);
    IPagedCollection<Product> page2 = await _productsRepository.GetPagedListAsync(
        pageSize: 10,
        orderBy: query => query.OrderBy(product => product.Price).ThenBy(product => product.Name)
    );
    // Indexers
    var a = page1[1].Price;
    var b = ((PagedList<Product>)page1)[2].Price;

    ...

    // Dictionary
    IPagedCollection<KeyValuePair<Guid, Product>> page1 = _productsRepository.GetPagedDictionary(product => product.Id, 20, 0, product => product.Price > 500);
    IPagedCollection<KeyValuePair<Guid, Product>> page2 = await _productsRepository.GetPagedDictionaryAsync(
        keySelector: product => product.Id,
        pageSize: 10,
        orderBy: query => query.OrderBy(product => product.Price).ThenBy(product => product.Name)
    );
    // Indexers
    var a = page1[1].Value.Price;
    var b = ((PagedDictionary<Guid, Product>)page1)[Guid.Parse("5926d548-c0b3-4c40-b37f-e89be7741024")].Price;
}

The before methods are same that

    GetAll(predicate, orderBy).ToPagedArray(pageSize, pageNumber);
    GetAll(predicate, orderBy).ToPagedListAsync(pageSize, pageNumber);
    GetAll(predicate, orderBy).ToPagedDictionary(keySelector, pageSize, pageNumber);