OrderSequenceGenerator 1.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package OrderSequenceGenerator --version 1.0.1
                    
NuGet\Install-Package OrderSequenceGenerator -Version 1.0.1
                    
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="OrderSequenceGenerator" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OrderSequenceGenerator" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="OrderSequenceGenerator" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add OrderSequenceGenerator --version 1.0.1
                    
#r "nuget: OrderSequenceGenerator, 1.0.1"
                    
#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.
#:package OrderSequenceGenerator@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=OrderSequenceGenerator&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=OrderSequenceGenerator&version=1.0.1
                    
Install as a Cake Tool

OrderSequenceGenerator

Zero-setup, high-performance, atomic order and application numbering generator for .NET 8 backed by PostgreSQL.

NuGet Version License: MIT

  • Zero Manual SQL: Automatically provisions PostgreSQL tables, columns matching pattern tokens, and unique composite constraints on application startup.
  • 17 Industry Presets: Pre-configured e-Seba, retail, POS, tax invoice, and custom patterns.
  • 100% Concurrency Safe: Uses atomic INSERT ... ON CONFLICT (...) DO UPDATE ... RETURNING sequence to guarantee zero gaps and zero duplicate numbers under extreme concurrency.
  • Automatic Walkthrough Script: Installing this NuGet package automatically places walkthrough.ps1 into the consumer project root for interactive command-line testing and setup!

๐Ÿ“ฆ Installation

Install via the .NET Core CLI:

dotnet add package OrderSequenceGenerator

Or via the Package Manager Console in Visual Studio:

Install-Package OrderSequenceGenerator

๐Ÿ› ๏ธ Step 1: Interactive Terminal Setup (walkthrough.ps1)

The moment you install this package and run dotnet build, walkthrough.ps1 is automatically delivered to your project root.

Open PowerShell in your project folder and run:

.\walkthrough.ps1

This interactive CLI tool allows you to:

  1. Preview all 17 pattern styles and live sample numbers.
  2. Select or enter any custom numbering pattern.
  3. Test your PostgreSQL connection interactively.
  4. Preview the exact SQL DDL and inspect the generated columns.
  5. Test atomic sequence increments directly in your terminal.

๐Ÿš€ Step 2: C# Setup & Registration (Zero Manual SQL)

Add the generator in your Program.cs. With AutoMigrate = true, you do not need to write migrations or SQL scriptsโ€”the engine derives all table columns directly from your pattern!

Example 1: e-Seba Government Pattern

using OrderSequenceGenerator;
using OrderSequenceGenerator.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Register with PostgreSQL atomic persistence
builder.Services.AddOrderSequenceGenerator(options =>
{
    options.ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection")!;
    
    // Choose from built-in presets:
    options.Pattern = OrderPatterns.ESebaCompact; // "{DISTRICT}{yyyy}{PREFIX}{MM}{dd}{SEQ:4}"
    
    // Optional configuration:
    options.TableName = "order_sequence"; // default table name
    options.AutoMigrate = true;           // auto-creates columns matching pattern tokens!
});

var app = builder.Build();
app.Run();

Example 2: Standard Retail / E-Commerce Pattern

builder.Services.AddOrderSequenceGenerator(options =>
{
    options.ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection")!;
    options.Pattern = OrderPatterns.StandardRetail; // "{PREFIX}-{yyyyMMdd}-{SEQ:4}"
    options.AutoMigrate = true;
});

Example 3: Custom Organization / Multi-Branch Pattern

You can define any combination of tokens:

builder.Services.AddOrderSequenceGenerator(options =>
{
    options.ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection")!;
    // Defines custom tokens: {COMPANY}, {DEPT}, {BRANCH}
    options.Pattern = "{COMPANY}-{DEPT}-{BRANCH}-{yyyyMMdd}-{SEQ:5}";
    options.AutoMigrate = true; // Automatically creates columns: company, dept, branch, year, month, day
});

๐Ÿ’ป Step 3: Generating Sequences in Code

Inject IOrderSequenceGenerator into any Controller, Minimal API endpoint, or Service.

In an ASP.NET Core Controller:

using Microsoft.AspNetCore.Mvc;
using OrderSequenceGenerator;

[ApiController]
[Route("api/[controller]")]
public class ApplicationsController : ControllerBase
{
    private readonly IOrderSequenceGenerator _generator;

    public ApplicationsController(IOrderSequenceGenerator generator)
    {
        _generator = generator;
    }

    [HttpPost]
    public async Task<IActionResult> CreateApplication([FromBody] ApplicationRequest request)
    {
        // Pass custom pattern tokens as an anonymous object:
        // (Date tokens yyyy, MM, dd are automatically populated from UTC now!)
        string appNumber = await _generator.NextAsync(new
        {
            District = request.District, // "MN051"
            Prefix = "E"
        });

        // Generated output: "MN05120260909E0001"
        return Ok(new 
        { 
            ApplicationNumber = appNumber, 
            Status = "Created" 
        });
    }
}

In a Minimal API:

app.MapPost("/api/orders", async (IOrderSequenceGenerator generator) =>
{
    string orderNo = await generator.NextAsync(new { Prefix = "ORD" });
    return Results.Ok(new { OrderNumber = orderNo }); // e.g. "ORD-20260909-0001"
});

Using a Dictionary:

var tokenValues = new Dictionary<string, string>
{
    { "DISTRICT", "MN051" },
    { "PREFIX", "E" }
};

string sequenceNo = await _generator.NextAsync(tokenValues);

Getting Just the Raw Numeric Sequence:

long rawNumber = await _generator.NextRawSequenceAsync(new { District = "MN051", Prefix = "E" });
// Returns: 1, 2, 3...

๐Ÿงช Unit Testing / Local Offline Scenarios

For unit tests or development environments without a live PostgreSQL database, use the in-memory provider:

// In your test project or mock setup:
services.AddInMemoryOrderSequenceGenerator(options =>
{
    options.Pattern = OrderPatterns.ESebaCompact;
});

๐Ÿ“‹ 17 Built-In Pattern Presets

Pattern Constant Pattern Template Example Output Reset Scope
OrderPatterns.ESebaCompact {DISTRICT}{yyyy}{PREFIX}{MM}{dd}{SEQ:4} MN0512026E09090001 Daily per District & Prefix
OrderPatterns.ESebaDelimited {DISTRICT}-{yyyy}{MM}{dd}-{PREFIX}-{SEQ:4} MN051-20260909-E-0001 Daily per District & Prefix
OrderPatterns.DeptCitizenService {DEPT}-{DISTRICT}-{yyyy}-{SEQ:4} REV-MN051-2026-0001 Yearly per Dept & District
OrderPatterns.StandardRetail {PREFIX}-{yyyyMMdd}-{SEQ:4} ORD-20260909-0001 Daily per Prefix
OrderPatterns.StoreCounterPos {PREFIX}-{STORE}-{POS}-{yyMM}-{SEQ:3} ORD-NY01-C1-2609-001 Monthly per Store & POS
OrderPatterns.MultiBranchRetail {PREFIX}-{BRANCH}-{yyyyMMdd}-{SEQ:4} ORD-MUM-20260909-0001 Daily per Branch
OrderPatterns.MonthlyInvoice {PREFIX}/{yyyy}/{MM}/{SEQ:4} INV/2026/09/0001 Monthly per Prefix
OrderPatterns.FiscalYearInvoice {PREFIX}/{yy}-{next_yy}/{SEQ:6} INV/26-27/000001 Fiscal Year
OrderPatterns.PurchaseOrder {PREFIX}-{yyyy}-{SEQ:5} PO-2026-00012 Yearly per Prefix
OrderPatterns.ShipmentWaybill {PREFIX}{yyyyMMdd}{SEQ:5} SHP2026090900001 Daily per Prefix
OrderPatterns.HealthcareToken {PREFIX}-{DEPT}-{yyMMdd}-{SEQ:3} TKN-CARD-260909-001 Daily per Dept
OrderPatterns.BankingTxn {PREFIX}-{yyyyMMdd}-{SEQ:6} TXN-20260909-000001 Daily per Prefix
OrderPatterns.LoanApplication {PREFIX}-{TYPE}-{yyyy}-{SEQ:4} LN-HL-2026-0001 Yearly per Loan Type
OrderPatterns.PaymentReceipt {PREFIX}/{yyyy}/{MM}/{SEQ:4} REC/2026/09/0001 Monthly per Prefix
OrderPatterns.SupportTicket {PREFIX}-{yyyy}-{SEQ:5} TKT-2026-00001 Yearly per Prefix
OrderPatterns.ContinuousAccount {PREFIX}-{SEQ:6} ACC-000042 Continuous (No Reset)

๐Ÿ—„๏ธ How the Database Schema Works

When AutoMigrate = true is enabled, the library inspects your pattern string and provisions PostgreSQL idempotently:

  1. Primary Key: id BIGSERIAL PRIMARY KEY.
  2. Dynamic Columns: A column is created for each custom token and date token found in the template string:
    • {DISTRICT} $\rightarrow$ district VARCHAR(50) NOT NULL
    • {PREFIX} $\rightarrow$ prefix VARCHAR(50) NOT NULL
    • {yyyy} $\rightarrow$ year INTEGER NOT NULL
    • {MM} $\rightarrow$ month INTEGER NOT NULL
    • {dd} $\rightarrow$ day INTEGER NOT NULL
  3. Sequence Counter: sequence BIGINT NOT NULL DEFAULT 0.
  4. Audit Timestamp: updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP.
  5. Composite Unique Constraint: A constraint UQ_<tableName>_scope UNIQUE (<token_columns>) guarantees that each unique combination of scope values maintains its own atomic sequence counter.

Atomic Concurrency Guarantee

All sequence numbers are generated using PostgreSQL atomic upsert:

INSERT INTO order_sequence (district, prefix, year, month, day, sequence, updated_at)
VALUES (@district, @prefix, @year, @month, @day, 1, CURRENT_TIMESTAMP)
ON CONFLICT (district, prefix, year, month, day)
DO UPDATE SET sequence = order_sequence.sequence + 1, updated_at = CURRENT_TIMESTAMP
RETURNING sequence;

This guarantees zero duplicate sequence numbers and zero gaps, even under high load across distributed servers.


๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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. 
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
1.0.2 116 9/9/2026
1.0.1 103 9/9/2026
1.0.0 99 9/9/2026

Version 1.0.1: Added detailed usage documentation in README, interactive walkthrough.ps1 setup instructions, Minimal API and Controller examples, and custom multi-branch pattern guide.