Nlabs.GenericRepository 9.0.0

dotnet add package Nlabs.GenericRepository --version 9.0.0                
NuGet\Install-Package Nlabs.GenericRepository -Version 9.0.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Nlabs.GenericRepository" Version="9.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Nlabs.GenericRepository --version 9.0.0                
#r "nuget: Nlabs.GenericRepository, 9.0.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Nlabs.GenericRepository as a Cake Addin
#addin nuget:?package=Nlabs.GenericRepository&version=9.0.0

// Install Nlabs.GenericRepository as a Cake Tool
#tool nuget:?package=Nlabs.GenericRepository&version=9.0.0                

Nlabs.GenericRepository

Overview

Nlabs.GenericRepository is a generic repository library for .NET applications, built on .NET 9. It provides a clean and efficient way to manage data access with repository and unit of work patterns. This library supports both synchronous and asynchronous methods and allows enabling or disabling tracking based on your requirements.

Dependency

This library requires .NET 9.

Installation

To install Nlabs.GenericRepository, use the following command:

dotnet add package Nlabs.GenericRepository

Usage Guide

UnitOfWork Implementation

The UnitOfWork pattern allows you to manage changes to multiple repositories in a single transaction. Implement the IUnitOfWork interface in your DbContext.
public class ApplicationDbContext : DbContext, IUnitOfWork
{
    public async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
    {
        return await base.SaveChangesAsync(cancellationToken);
    }

    public int SaveChanges()
    {
        return base.SaveChanges();
    }
}

Repository Implementation

Creating a Repository
Define a repository interface by implementing IRepository<T> for your entity.
public interface IUserRepository : IRepository<User>
{
    // Custom methods for User can be added here
}
Then, create a concrete class for the repository that inherits from Repository<T, ApplicationDbContext>.
public class UserRepository : Repository<User, ApplicationDbContext>, IUserRepository
{
    public UserRepository(ApplicationDbContext context) : base(context)
    {
    }
}

Service Layer Example

In your service layer, inject IUserRepository and IUnitOfWork to manage data operations.
public sealed class UserService
{
    private readonly IUserRepository _userRepository;
    private readonly IUnitOfWork _unitOfWork;

    public UserService(IUserRepository userRepository, IUnitOfWork unitOfWork)
    {
        _userRepository = userRepository;
        _unitOfWork = unitOfWork;
    }

    public async Task AddAsync(User user, CancellationToken cancellationToken)
    {
        await _userRepository.AddAsync(user, cancellationToken);
        await _unitOfWork.SaveChangesAsync(cancellationToken);
    }

    public async Task<User?> GetByIdAsync(Guid id, CancellationToken cancellationToken)
    {
        return await _userRepository.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
    }

    public async Task<IList<User>> GetAllAsync(CancellationToken cancellationToken)
    {
        return await _userRepository.GetAll().ToListAsync(cancellationToken);
    }
}

Dependency Injection

Configure IUserRepository and IUnitOfWork in Program.cs(IoC) for dependency injection.
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped<IUnitOfWork>(provider => provider.GetRequiredService<ApplicationDbContext>());

Available Methods

The IRepository<T> interface provides a comprehensive set of methods for CRUD operations and includes tracking options.
public interface IRepository<T> where T : class
{
    // Fetching records
    IQueryable<T> GetAll(bool isTrackingActive = false);
    IQueryable<T> Where(Expression<Func<T, bool>> predicate, bool isTrackingActive = false);
    T? FirstOrDefault(Expression<Func<T, bool>> predicate, bool isTrackingActive = false);
    Task<T?> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default, bool isTrackingActive = false);

    // Checking existence
    bool Any(Expression<Func<T, bool>> predicate);
    Task<bool> AnyAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default);

    // Adding records
    void Add(T entity);
    Task AddAsync(T entity, CancellationToken cancellationToken = default);
    void AddRange(IEnumerable<T> entities);
    Task AddRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken = default);

    // Updating records
    void Update(T entity);
    void UpdateRange(IEnumerable<T> entities);

    // Deleting records
    void Delete(T entity);
    void DeleteRange(IEnumerable<T> entities);
    T DeleteById(string id);
    Task<T> DeleteByIdAsync(string id, CancellationToken cancellationToken = default);

    // Counting records
    int Count();
    int Count(Expression<Func<T, bool>> predicate);
    Task<int> CountAsync(CancellationToken cancellationToken = default);
    Task<int> CountAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default);
}

Example Usage

Below are example usages of the repository methods, showcasing both tracking and non-tracking options.
1. Fetching All Records
Non-Tracking (Default):
var users = await _userRepository.GetAll().ToListAsync(cancellationToken);
Tracking:
var users = await _userRepository.GetAll(true).ToListAsync(cancellationToken);
2. Fetching Records Based on a Condition
Non-Tracking (Default):
var user = await _userRepository.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
Tracking:
var user = await _userRepository.FirstOrDefaultAsync(p => p.Id == id, cancellationToken, true);
3. Checking Existence
var isUserExists = _userRepository.Any(p => p.Id == id);
4. Adding Records
var user = new User { Id = Guid.NewGuid(), Name = "John Doe" };
_userRepository.Add(user);
5. Updating Records
var user = await _userRepository.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
user.Name = "Jane Doe";
_userRepository.Update(user);
6. Deleting Records
var user = await _userRepository.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
_userRepository.Delete(user);
7. Counting Records
var userCount = _userRepository.Count();

License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
9.0.0 38 11/14/2024
1.0.1 77 10/13/2024
1.0.0 134 6/15/2024