ISO 4217 Currency Reference for .NET — Strongly Typed and Production-Ready

Working with currencies in .NET often looks simple — until it becomes a mess. String-based codes, inconsistent casing, withdrawn currencies, special units, and edge cases that silently break your logic. If you’ve ever dealt with payments, rates, accounting, or financial integrations, you’ve likely seen horrors like:

if (currencyCode == "usd" || currencyCode == "Usd" || currencyCode == "USD")
{
    // ...
}

or the “improved” version:

if (string.Equals(currencyCode, "usd", StringComparison.OrdinalIgnoreCase))
{
    // ...
}

or even worse:

if (currency == "XXX") { /* ??? */ }
if (currency == "BYR") { /* replaced by BYN */ }
// ...

All of this happens because currencies are treated as plain strings.
But ISO 4217 is a standard. We should be able to consume it in a strongly typed way.
I explored existing solutions… but most were:

  • too heavy,
  • too dynamic,
  • not strongly typed,
  • outdated,
  • not auto-updated with ISO data.
    So I asked myself:

What if ISO currency types could be generated at compile time with a Source Generator?

That idea became:

HawkN.Currency.Reference.Iso4217

🔗 NuGet: https://www.nuget.org/packages/HawkN.Currency.Reference.Iso4217
📦 GitHub: https://github.com/HawkN113/Currency.Reference.Iso4217

A lightweight, zero-dependency, source-generated, production-ready ISO 4217 reference library for .NET.

🚀 Features

✔ Strongly typed enum: CurrencyCode (No more “USD” strings. Pure compile-time safety)
✔ Historical & withdrawn currencies included
EUR replacements, old European national currencies, BYR → BYN, and more.
✔ Full ISO 4217 data embedded
Original + friendly names + replacements + special units.
✔ Query builder for filtering
Get exactly the currencies you need.
✔ Fast, static, zero-allocation lookups
Everything is generated at compile time.
✔ No dependencies
Just install & use.
✔ CI-driven updates
GitHub Actions for:

  • auto-publishing,
  • formatting,
  • tests,
  • security validation.

📦 Installation

CLI:

dotnet add package HawkN.Currency.Reference.Iso4217 --version 8.0.1

NuGet Package Manager:

Install-Package HawkN.Currency.Reference.Iso4217 -Version 8.0.1

🧩 Getting Started

Register:

services.AddCurrencyService();

Example in a console app:

using var host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.AddCurrencyService();
    })
    .Build();

Resolve:

var currencyService = provider.GetRequiredService<ICurrencyService>();

Inject (Minimal API):

app.MapGet("/currencies", ([FromServices] ICurrencyService svc) => svc...);

🔍 Usage Examples

Query currencies

var currencies = currencyService.Query()
    .Includes
        .Type(CurrencyType.Fiat)
        .Type(CurrencyType.SpecialUnit)
        .Type(CurrencyType.SpecialReserve)
        .Type(CurrencyType.PreciousMetal)
    .Build();

Currency Types:

  • Fiat
    Standard government-issued currencies.
    Examples: USD, EUR, JPY

  • SpecialUnit
    Non-sovereign institutional units.
    Examples: SDR, IMF units, etc.

  • SpecialReserve
    Reserve assets used by central banks.

  • PreciousMetal
    Value pegged to metals.
    Examples: XAU, XAG, XPT, XPD

If you only need fiat:

var fiat = currencyService.Query()
    .Includes.Type(CurrencyType.Fiat)
    .Build();

Excluding currencies

var filtered = currencyService.Query()
    .Includes.Type(CurrencyType.Fiat)
    .Without(w => w.Codes(nameof(CurrencyCode.EUR), nameof(CurrencyCode.USD)))
    .Build();

Advanced search

var selected = currencyService.Query()
    .Includes.Type(CurrencyType.Fiat)
    .Where(x => x.Code is "EUR" or "USD")
    .Build();

Validation

var ok = currencyService.TryValidate("AFN", out var result);

or:

var ok = currencyService.TryValidate(CurrencyCode.AFN, out var result);

Lookup

By string:

var afn = currencyService.Get("AFN");

By enum:

var afn = currencyService.Get(CurrencyCode.AFN);

Historical currencies

var historical = currencyService.GetAllHistorical();
foreach (var c in historical)
{
    Console.WriteLine($"{c.Code} - {c.Name} (Withdrawn: {c.WithdrawnOn})");
}

🌟 Why This Library?

Use HawkN.Currency.Reference.Iso4217 if you want:

  • compile-time safety instead of EUR strings
  • ISO-compliant data without manual maintenance
  • extremely fast lookups
  • great developer experience (IntelliSense everything)
  • AOT-ready, reflection-free library
  • static, deterministic data
  • automatic updates via CI workflows

🙌 Final Thoughts

This project started as a small experiment — “Can I generate all ISO 4217 currencies with a Source Generator?
Then it became a clean, fast, production-ready solution that removes all currency-related pain from .NET apps.
If you deal with payments, rates, financial systems, or even basic validation — this package will save you time and bugs.
🔗 GitHub: https://github.com/HawkN113/Currency.Reference.Iso4217
🔗 NuGet: https://www.nuget.org/packages/HawkN.Currency.Reference.Iso4217

Happy coding!

Similar Posts