CleanArch.Repository
0.3.1
dotnet add package CleanArch.Repository --version 0.3.1
NuGet\Install-Package CleanArch.Repository -Version 0.3.1
<PackageReference Include="CleanArch.Repository" Version="0.3.1" />
<PackageVersion Include="CleanArch.Repository" Version="0.3.1" />
<PackageReference Include="CleanArch.Repository" />
paket add CleanArch.Repository --version 0.3.1
#r "nuget: CleanArch.Repository, 0.3.1"
#:package CleanArch.Repository@0.3.1
#addin nuget:?package=CleanArch.Repository&version=0.3.1
#tool nuget:?package=CleanArch.Repository&version=0.3.1
CleanArchitecture Repository
CleanArch.Repository provides a clean, extensible, and testable implementation of the Repository and Unit of Work patterns, designed to fit perfectly within a Clean Architecture solution.
It supports generic repositories, specification execution, and EF Core integration, while keeping your domain model persistence-agnostic.
โจ Features
- Generic Repository Abstractions
IRepository<T>IReadRepository<T>- Async-first APIs
- Unit of Work Support
IUnitOfWorkfor committing and managing transactions
- Full Specification Support
- Works seamlessly with
CleanArch.Specification
- Works seamlessly with
- Entity Framework Core Ready
- Clean extensions for
DbContext
- Clean extensions for
- Highly Testable
- Replace repositories with mocks or in-memory implementations in unit tests
- Clean Architecture Friendly
- Keeps your Application & Domain layers free from EF Core details
๐ฆ Installation
Install via NuGet:
dotnet add package CleanArch.Repository
๐ Concepts
Repository Pattern
Encapsulates data access logic into a simple, testable abstraction.
Example abstraction:
public interface IReadRepository<T>
{
Task<T?> GetByIdAsync<TId>(TId id, CancellationToken cancellationToken = default) where TId : notnull;
Task<T?> FirstOrDefaultAsync(ISpecification<T> specification, CancellationToken cancellationToken = default);
Task<TResult?> FirstOrDefaultAsync<TResult>(ISpecification<T, TResult> specification, CancellationToken cancellationToken = default);
Task<TResult?> SingleOrDefaultAsync<TResult>(ISingleResultSpecification<T, TResult> specification, CancellationToken cancellationToken = default);
Task<List<T>> ListAsync(ISpecification<T> specification, CancellationToken cancellationToken = default);
...
}
Unit of Work Pattern
Ensures atomic operations โ commit multiple repository actions in a single transaction:
public interface IUnitOfWork
{
Task<int> CommitAsync(CancellationToken cancellationToken = default);
}
๐ Usage Examples
1. Basic Repository Usage
public class UserService
{
private readonly IRepository<User> _repo;
private readonly IUnitOfWork _uow;
public UserService(IRepository<User> repo, IUnitOfWork uow)
{
_repo = repo;
_uow = uow;
}
public async Task<Guid> CreateUserAsync(string name)
{
var user = new User(name);
await _repo.AddAsync(user);
await _uow.CommitAsync();
return user.Id;
}
}
2. Fetching Data with Specification
Assume you have this specification:
public class ActiveUsersSpecification : Specification<User>
{
public ActiveUsersSpecification()
{
Query.Where(u => u.IsActive);
}
}
Use it like this:
var spec = new ActiveUsersSpecification();
var activeUsers = await _repo.ListAsync(spec);
3. Using Unit of Work with Transactions
public async Task TransferMoney(Guid fromId, Guid toId, decimal amount)
{
var from = await _repo.GetByIdAsync(fromId);
var to = await _repo.GetByIdAsync(toId);
from.Withdraw(amount);
to.Deposit(amount);
await _uow.BeginTransactionAsync();
try
{
await _repo.UpdateAsync(from);
await _repo.UpdateAsync(to);
await _uow.CommitTransactionAsync();
}
catch
{
await _uow.RollbackTransactionAsync();
throw;
}
}
4. Example: EF Core DbContext Integration
services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));
services.AddScoped(typeof(IReadRepository<>), typeof(EfRepository<>));
services.AddScoped<IUnitOfWork, EfUnitOfWork>();
Then repositories become available everywhere via DI.
๐งช Unit Testing with In-Memory Repositories
Example with a fake repo:
var repo = new InMemoryRepository<User>();
var uow = new NoOpUnitOfWork();
await repo.AddAsync(new User("Reza"));
var result = await repo.ListAsync(new ActiveUsersSpecification());
This keeps your domain/application tests isolated from EF Core.
๐ค Contributing
Pull requests and discussions are welcome!
Please ensure new features include tests and follow Clean Architecture best practices.
๐ License
This project is licensed under the MIT License. See the LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- CleanArch.Domain.Abstractions (>= 0.3.1)
- CleanArch.Specification (>= 0.3.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on CleanArch.Repository:
| Package | Downloads |
|---|---|
|
CleanArch.Repository.EntityFramework
EntityFramework repositories for Clean Architecture. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.3.1 | 500 | 12/11/2025 |