ArchPillar.Extensions.Localization
1.5.0-preview9
dotnet add package ArchPillar.Extensions.Localization --version 1.5.0-preview9
NuGet\Install-Package ArchPillar.Extensions.Localization -Version 1.5.0-preview9
<PackageReference Include="ArchPillar.Extensions.Localization" Version="1.5.0-preview9" />
<PackageVersion Include="ArchPillar.Extensions.Localization" Version="1.5.0-preview9" />
<PackageReference Include="ArchPillar.Extensions.Localization" />
paket add ArchPillar.Extensions.Localization --version 1.5.0-preview9
#r "nuget: ArchPillar.Extensions.Localization, 1.5.0-preview9"
#:package ArchPillar.Extensions.Localization@1.5.0-preview9
#addin nuget:?package=ArchPillar.Extensions.Localization&version=1.5.0-preview9&prerelease
#tool nuget:?package=ArchPillar.Extensions.Localization&version=1.5.0-preview9&prerelease
ArchPillar.Extensions.Localization
A user-interface translation library for .NET. Write each translatable string once, at the call site, as an in-code default in ICU MessageFormat; a Roslyn generator extracts it at compile time for translators; at runtime, translated catalogs (ARB, XLIFF 2.1, or Portable Object) load as pluggable overrides. The in-code default is always the source of truth and the terminal fallback, so an app with zero translation files runs correctly and partial translations degrade gracefully key by key.
Why?
The usual .resx + IStringLocalizer flow inverts the source of truth: the key is a lookup into a
resource file, and the call site says nothing about what the string actually is. Strings drift from
their translations, a missing resource yields the bare key, and nothing checks at build time that a
string was extracted or that its placeholders line up.
This library puts the source string at the call site and makes the build do the bookkeeping. The default renders even with no catalogs loaded — there is no "missing resource" state, only "no override yet" — while a source generator extracts every call site and an analyzer flags a non-constant key, invalid ICU, or a placeholder with no argument before you ship. Translations layer over the defaults in one ambient store that needs no DI, so even an exception thrown before any container exists localizes.
Quick Start
using static ArchPillar.Extensions.Localization.Localizer;
using System.Globalization;
// Translate anywhere with a using static, the way `using static System.Console;` gives you WriteLine.
// "greeting" is the key; "Hello {name}!" is the in-code default (the source text and the fallback).
string Greet(string name) => Translate("greeting", "Hello {name}!", ("name", name));
Console.WriteLine(Greet("Ada")); // "Hello Ada!" (the in-code default)
CultureInfo.CurrentUICulture = CultureInfo.GetCultureInfo("de");
Console.WriteLine(Greet("Ada")); // "Hallo Ada!" once a de catalog is loaded
Translate goes through the process-wide ambient store, reachable with no services (or call
Localizer.Default.Translate(...) without the using static). Translations come from a
Translations/de.arb file beside the binary (loaded automatically), an embedded catalog, or an extra
provider layered through LocalizerOptions.Providers and Localizer.Initialize(...). Scope keys by
category with ILocalizer<T> as an app grows.
Dependency injection and IStringLocalizer
In a host, add the ArchPillar.Extensions.Localization.DependencyInjection package and register the
library; it feeds the same ambient store and registers ILocalizer, ILocalizer<T>, and a composing
IStringLocalizer adapter (which falls through to an existing .resx factory, easing migration):
services.AddArchPillarLocalization(new LocalizerOptions { SourceCulture = "en" });
UseRequestLocalization drives the culture in ASP.NET Core — no extra wiring.
What's in the box
- Categories —
ILocalizer<T>scopes keys bytypeof(T), theILogger<T>model; no namespaces to manage. - The ambient store — one process-wide, layered, DI-free store reachable from anywhere, or an
instantiable
LocalizationContextconstructed directly for a fully static-free setup. - ICU MessageFormat — arguments, typed number/currency/compact formatting,
plural/selectordinal/select, embedded CLDR plural + number data. - Standard formats — XLIFF 2.1 (default), ARB, Portable Object, bundled (no extra packages).
- Files / embedded / satellites — loose files by default (trim/AOT-safe); opt-in satellite embedding.
- Tooling — a source generator, the
APLanalyzer diagnostics, and thedotnet aplCLI, all bundled.
No dependencies beyond the Base Class Library.
Documentation
See the localization documentation for getting started, every feature, production recommendations, and the design spec.
License
MIT. See LICENSE.
| Product | Versions 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 is compatible. 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 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
- ArchPillar.Extensions.Localization.Abstractions (>= 1.5.0-preview9)
- ArchPillar.Extensions.Localization.MessageFormat (>= 1.5.0-preview9)
-
net8.0
- ArchPillar.Extensions.Localization.Abstractions (>= 1.5.0-preview9)
- ArchPillar.Extensions.Localization.MessageFormat (>= 1.5.0-preview9)
-
net9.0
- ArchPillar.Extensions.Localization.Abstractions (>= 1.5.0-preview9)
- ArchPillar.Extensions.Localization.MessageFormat (>= 1.5.0-preview9)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on ArchPillar.Extensions.Localization:
| Package | Downloads |
|---|---|
|
ArchPillar.Extensions.Localization.DependencyInjection
Dependency-injection registration for ArchPillar.Extensions.Localization. Configures the ambient store from LocalizerOptions and registers the native localization views — ILocalizer, ILocalizer<T>, and a concrete Localizer — for injection. The core runtime stays dependency-free; this adapter is optional. For IStringLocalizer interop while migrating, add ArchPillar.Extensions.Localization.StringLocalizer. |
|
|
ArchPillar.Extensions.Localization.StringLocalizer
IStringLocalizer interop for ArchPillar.Extensions.Localization: a migration on-ramp that adapts the localizer to IStringLocalizer/IStringLocalizer<T> and composes over an existing ResourceManager/.resx factory, so an app adopting the library from an IStringLocalizer codebase keeps its existing translations resolving. Reference it during migration; drop it once your code no longer depends on IStringLocalizer. |
|
|
ArchPillar.Extensions.Localization.AspNetCore
ASP.NET Core hosting helpers for ArchPillar.Extensions.Localization: serve ARB/XLIFF/PO translation catalogs as static files so a hosted Blazor WebAssembly client can fetch them over HTTP. The static file middleware 404s unknown extensions by default; these helpers register the catalog content types in one call. The core runtime stays dependency-free; this adapter is optional. |
|
|
ArchPillar.Extensions.Localization.WebAssembly
Blazor WebAssembly startup helper for ArchPillar.Extensions.Localization: a WebAssemblyHost extension that registers HTTP/manifest catalog loading over the ambient localizer and loads the active language up front, so a browser client with no readable file system is localized from the first render and fetches additional languages on demand. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.5.0-preview9 | 93 | 8/3/2026 |
| 1.5.0-preview8 | 82 | 7/31/2026 |
| 1.5.0-preview7 | 78 | 7/30/2026 |
| 1.5.0-preview6 | 85 | 7/29/2026 |
| 1.5.0-preview5 | 73 | 7/26/2026 |
| 1.5.0-preview4 | 80 | 7/25/2026 |
| 1.5.0-preview3 | 112 | 6/17/2026 |
| 1.5.0-preview2 | 109 | 6/17/2026 |
| 1.5.0-preview15 | 111 | 8/21/2026 |
| 1.5.0-preview14 | 103 | 8/17/2026 |
| 1.5.0-preview13 | 83 | 8/11/2026 |
| 1.5.0-preview12 | 94 | 8/10/2026 |
| 1.5.0-preview11 | 88 | 8/10/2026 |
| 1.5.0-preview10 | 88 | 8/6/2026 |
| 1.5.0-preview1 | 97 | 6/16/2026 |
| 1.4.4-preview | 92 | 6/15/2026 |
| 1.4.3-preview | 91 | 6/14/2026 |
| 1.4.2-preview | 78 | 6/14/2026 |
| 1.4.1-preview | 80 | 6/14/2026 |
| 1.4.0-preview | 93 | 6/13/2026 |