ISO 4217 통화 레퍼런스 for .NET — 강력한 타입 지정 및 프로덕션 레디
Source: Dev.to
Overview
.NET에서 통화를 다루는 일은 겉보기에 간단해 보이지만, 실제로는 엉망이 될 수 있습니다. 문자열 기반 코드, 일관성 없는 대소문자, 폐지된 통화, 특수 단위, 그리고 다양한 예외 상황이 로직을 조용히 깨뜨릴 수 있습니다. 흔히 발생하는 함정은 다음과 같습니다:
if (currencyCode == "usd" || currencyCode == "Usd" || currencyCode == "USD")
{
// ...
}
또는 “개선된” 버전:
if (string.Equals(currencyCode, "usd", StringComparison.OrdinalIgnoreCase))
{
// ...
}
그리고 더 나쁜 경우:
if (currency == "XXX") { /* ??? */ }
if (currency == "BYR") { /* replaced by BYN */ }
이 모든 문제는 통화를 단순 문자열로 취급하기 때문에 발생합니다. ISO 4217은 표준이므로, 이를 강력히 타입화된 방식으로 사용할 수 있어야 합니다.
The Idea
컴파일 타임에 Source Generator를 사용해 ISO 통화 타입을 생성합니다. 그 결과가 HawkN.Currency.Reference.Iso4217 라이브러리입니다.
- NuGet:
- GitHub:
.NET용 경량, 무의존성, 소스 생성 기반, 프로덕션 준비된 ISO 4217 레퍼런스 라이브러리입니다.
Installation
CLI
dotnet add package HawkN.Currency.Reference.Iso4217 --version 8.0.1
Package Manager
Install-Package HawkN.Currency.Reference.Iso4217 -Version 8.0.1
Registration
services.AddCurrencyService();
Basic Usage
Console Application
using var host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddCurrencyService();
})
.Build();
var currencyService = host.Services.GetRequiredService<ICurrencyService>();
Minimal API Injection
app.MapGet("/currencies", ([FromServices] ICurrencyService svc) => svc.Query().Build());
Querying Currencies
Include Specific Types
var currencies = currencyService.Query()
.Includes
.Type(CurrencyType.Fiat)
.Type(CurrencyType.SpecialUnit)
.Type(CurrencyType.SpecialReserve)
.Type(CurrencyType.PreciousMetal)
.Build();
Currency Types
- Fiat – 예:
USD,EUR,JPY - SpecialUnit – 예:
SDR, IMF 단위 - SpecialReserve
- PreciousMetal – 예:
XAU,XAG,XPT,XPD
Filter Only Fiat Currencies
var fiat = currencyService.Query()
.Includes.Type(CurrencyType.Fiat)
.Build();
Exclude Specific Codes
var filtered = currencyService.Query()
.Includes.Type(CurrencyType.Fiat)
.Without(w => w.Codes(nameof(CurrencyCode.EUR), nameof(CurrencyCode.USD)))
.Build();
Conditional Selection
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);
또는 강력히 타입화된 enum을 사용:
var ok = currencyService.TryValidate(CurrencyCode.AFN, out var result);
Retrieval
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})");
}
Benefits
- 문자열 리터럴 대신 컴파일 타임 안전성 제공.
- 수동 유지보수가 필요 없는 ISO‑준수 데이터.
- 매우 빠른 조회 속도.
- 어디서든 IntelliSense가 제공되는 뛰어난 개발자 경험.
- AOT‑지원 및 리플렉션 불필요.
- 정적이며 결정적인 데이터.
- CI 워크플로우를 통한 자동 업데이트.
Project Background
이 프로젝트는 작은 실험으로 시작되었습니다: “Source Generator로 모든 ISO 4217 통화를 생성할 수 있을까?”
- GitHub:
- NuGet:
즐거운 코딩 되세요!