Skip to ContentSkip to Content
Introduction

Forge.Repository

A production-grade, database-agnostic repository pattern for .NET 10.

Forge.Repository provides a clean, consistent data-access API that works identically across SQL Server, PostgreSQL, Oracle, MySQL, and MariaDB. Install the core package, add one provider package, register in DI - and your repository, unit of work, audit trail, and criteria pattern are ready to use.

dotnet add package Forge.Repository dotnet add package Forge.Repository.SqlServer # or PostgreSql / Oracle / MySql

Why Forge.Repository?

Most projects end up with the same boilerplate: a generic IRepository<T>, a unit of work wrapper, some audit fields on base models, and a handful of raw SQL escape hatches. Forge.Repository packages all of that into a single, tested, NuGet-published library so you stop copying it between solutions.

Pain pointWhat Forge provides
Repeated CRUD boilerplateIRepositoryAsync<T> with full async CRUD, bulk ops, predicates
Switching databasesSwap one AddForge* call - zero application code changes
Complex query logic scattered in servicesCriteria pattern - queries in dedicated, testable objects
Manual audit timestampsIAuditableBaseModel with OnCreate / OnUpdate / OnDelete hooks
ORM limitationsFindAllBySql, ExecuteSqlRaw with full async and cancellation
Transaction coordinationIUnitOfWork.SaveChangesAsync commits all repositories at once

Package Ecosystem

Forge.Repository is split into a core package and provider packages. Install the core package first, then add exactly one provider:

PackagePurpose
Forge.RepositoryCore interfaces, base models, criteria, unit of work - always required
Forge.Repository.SqlServerMicrosoft SQL Server via Microsoft.EntityFrameworkCore.SqlServer
Forge.Repository.PostgreSqlPostgreSQL via Npgsql.EntityFrameworkCore.PostgreSQL
Forge.Repository.OracleOracle via Oracle.EntityFrameworkCore
Forge.Repository.MySqlMySQL and MariaDB via Pomelo.EntityFrameworkCore.MySql

Always use the same version for Forge.Repository and your provider package. Mixed versions will cause runtime errors.


At a Glance

// 1. Register — Program.cs builder.Services.AddForgeRepositorySqlServer<AppDbContext>( connectionString: builder.Configuration.GetConnectionString("ConnectionString")!, poolingOptions: new ForgeDbContextPoolingOptions { EnablePooling = true, MinPoolSize = 5, MaxPoolSize = 20 }, configure: tuner => { tuner.SetRetry(3).SetTimeout(30).EnableLazyLoading(); }); // 2. Define your entity public class Order : IAuditableBaseModel { public string Id { get; set; } = Ulid.NewUlid().ToString(); public string CustomerId { get; set; } = string.Empty; public decimal Total { get; set; } public DateTime CreatedOn { get; set; } public DateTime ModifiedOn { get; set; } public string CreatedBy { get; set; } = string.Empty; public string ModifiedBy { get; set; } = string.Empty; public bool IsDeleted { get; set; } public void OnCreate() => CreatedOn = DateTime.UtcNow; public void OnUpdate() => ModifiedOn = DateTime.UtcNow; public void OnDelete() => IsDeleted = true; } // 3. Use in a service public class OrderService(IUnitOfWork uow) { private readonly IRepositoryAsync<Order> _orders = uow.GetRepositoryAsync<Order>(); public Task<IList<Order>> GetAllAsync(CancellationToken ct) => _orders.GetAllAsync(ct); public Task<Order> GetAsync(string id, CancellationToken ct) => _orders.GetByIdAsync(id, ct); public async Task PlaceAsync(Order order, CancellationToken ct) { await _orders.AddAsync(order, ct); await uow.SaveChangesAsync(ct); } }

Quick Navigation


Source & Issues

Forge.Repository is closed source - the compiled packages are published to NuGet.org under a proprietary license. Source will open soon.