Sanet.Localization
0.3.0
dotnet add package Sanet.Localization --version 0.3.0
NuGet\Install-Package Sanet.Localization -Version 0.3.0
<PackageReference Include="Sanet.Localization" Version="0.3.0" />
<PackageVersion Include="Sanet.Localization" Version="0.3.0" />
<PackageReference Include="Sanet.Localization" />
paket add Sanet.Localization --version 0.3.0
#r "nuget: Sanet.Localization, 0.3.0"
#:package Sanet.Localization@0.3.0
#addin nuget:?package=Sanet.Localization&version=0.3.0
#tool nuget:?package=Sanet.Localization&version=0.3.0
Sanet.Localization
Culture-invariant localization engine for .NET. Consuming applications provide their own embedded .resx resource sets; the engine reads them without relying on CultureInfo or IStringLocalizer, which is the only approach proven to work on WebAssembly and invariant-globalization builds.
Design
ILocalizationServiceexposes the activeLanguage, the list of available languages, language switching andGetString(key), plus aLanguageChangedevent (contract aligned withSanet.MakaMek.Localization).LocalizationServiceimplements the contract and is responsible only for active-language management: it tracks the active language, caches its strings (with a separate cache for the default language), and resolves values falling back from the active language to the default language to the raw key.ILocalizationResourcesProvider(inProviders/) is the resource-management seam: it discovers the available languages and loads the key/value strings for a given language. Languages available to the service come entirely from the provider.EmbeddedResourcesProvideris the first implementation of the provider, reading embedded.resources(compiled from the app's.resxfiles) from a resource assembly and base name supplied at construction. Languages are discovered viaAssembly.GetManifestResourceNames(), values are read withSystem.Resources.ResourceReader. The default language is embedded as{resourceBaseName}.resourcesand every additional language as{resourceBaseName}-{code}.resources. Each resource file may contain alanguage_namekey — a regular key/value pair used as the language's display name (omit it when not needed). Other providers (file system, network, non-resxformats, in-memory dictionaries for tests) can be added by implementingILocalizationResourcesProviderand passing it toAddLocalizationornew LocalizationService(provider).- No UI-framework dependency; the only external dependency is
Microsoft.Extensions.DependencyInjection.Abstractions.
Usage
Given resources embedded in MyApp as MyApp.Resources.Strings.resources (default/English) and MyApp.Resources.Strings-be.resources (Belarusian):
services.AddLocalization(new EmbeddedResourcesProvider(typeof(SomeAppType).Assembly, "MyApp.Resources.Strings"));
Then resolve strings through constructor-injected ILocalizationService.GetString(key).
Resource naming convention:
- default language:
Strings.resx→ embedded as{resourceBaseName}.resources - additional languages:
Strings-be.resx→ embedded as{resourceBaseName}-{code}.resources
Each file may define a language_name key holding the language's display name, e.g. <data name="language_name"><value>беларуская</value></data>.
To supply resources from a custom source, implement ILocalizationResourcesProvider and pass it to AddLocalization.
Multiple resource sources
CompositeResourcesProvider (in Providers/) combines several ILocalizationResourcesProvider instances — different resource families in one assembly, resources of referenced assemblies, or a mix of embedded and custom providers — so that strings for one language can come from several sets:
// Two resource families in one assembly (e.g. Strings and Errors)
services.AddLocalization(new CompositeResourcesProvider(
new EmbeddedResourcesProvider(typeof(SomeAppType).Assembly, "MyApp.Resources.Strings"),
new EmbeddedResourcesProvider(typeof(SomeAppType).Assembly, "MyApp.Resources.Errors")));
// Application resources overriding resources of a referenced shared assembly
services.AddLocalization(new CompositeResourcesProvider(
new EmbeddedResourcesProvider(typeof(SharedMarker).Assembly, "Shared.Resources.Strings"),
new EmbeddedResourcesProvider(typeof(AppMarker).Assembly, "MyApp.Resources.Strings")));
// Embedded resources combined with a custom provider (later provider wins on key conflicts)
services.AddLocalization(new CompositeResourcesProvider(
new EmbeddedResourcesProvider(typeof(SomeAppType).Assembly, "MyApp.Resources.Strings"),
new MyCustomResourcesProvider()));
Composition rules:
- Priority: input order defines priority, from lowest to highest. Later providers override duplicate keys and duplicate display names, so an extending application goes last.
- Languages: the
LanguageDiscoveryPolicycontrols which languages are exposed —Union(default: every code advertised by any provider),Intersection(only codes advertised by every provider) orPrimaryOnly(only the codes of the first provider). Languages are matched by code, not by record equality. - Default language: all providers must agree on the default language code; otherwise an
ApplicationExceptionis thrown. - Missing language: a provider that does not advertise the requested language is skipped for that language; keys of that provider are still covered by the default-language fallback of
GetString. - Fallback: key resolution is unchanged — active language, then default language, then the raw key.
Note that each EmbeddedResourcesProvider reads only the resources of the assembly and base name supplied at construction; no assembly scanning occurs.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Sanet.Localization:
| Package | Downloads |
|---|---|
|
Sanet.MakaMek.Core
An Attempt of Classic BattleTech game implementation. Game Logic |
|
|
Sanet.MakaMek.Avalonia
Avalonia UI frontend for MakaMek game |
|
|
Sanet.MakaMek.Map
An Attempt of Classic BattleTech game implementation. Map Logic |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.3.0 | 4,831 | 10/12/2026 |
| 0.3.0-preview | 92 | 10/12/2026 |
| 0.2.0 | 300 | 9/21/2026 |
| 0.2.0-preview | 91 | 9/21/2026 |
| 0.1.0 | 286 | 9/21/2026 |
| 0.1.0-preview | 92 | 9/21/2026 |