Localized text whose identity is stored.
Most localization libraries answer one question: what does this string say in the reader's language.
This one answers a narrower one. Sometimes the text is also a key — a verdict is filed against a record's title, a rule matches on it, a database row points at it. Translate that text in place and every stored reference is orphaned. Not a crash; a quieter kind of wrong.
So this library keeps three rules, and makes the compiler hold them for you:
| Rule | What it means |
|---|---|
| Keys are identity | The neutral English is what you store. The reader's culture is resolved later, from the key. |
The .resx is the only declaration |
A generator turns it into typed members, so a renamed key moves its callers and a deleted one stops compiling. |
| The vocabulary is closed | An analyzer refuses a key invented at a call site — it would resolve to no text and read as a finished record. |
dotnet add package SimpleLocalizations
1. Point at a .resx. That is the whole declaration — every setting defaults from the file.
<ItemGroup>
<VocabularyResource Include="Strings.resx" />
</ItemGroup>2. Author the words, keyed lowercase. The <comment> becomes the generated member's XmlDoc.
<data name="greeting" xml:space="preserve">
<value>Hello, {0}</value>
<comment>Becomes the generated member's XmlDoc.</comment>
</data>3. Name the member, never the key.
var text = StringsKeys.Catalog(new TextCultures("en-US", "sv-SE"));
text.Get(StringsKeys.Greeting); // "Hello, {0}" for an English reader, "Hej, {0}" for a Swedish reader
text.Format(StringsKeys.Greeting, "world"); // "Hello, world", or "Hej, world" for a Swedish reader
text.Neutral(StringsKeys.Greeting, "world"); // "Hello, world" whoever is reading — what you persistStringsKeys is generated from Strings.resx. The class name, namespace, resource name and key type all
follow the file, and each one is overridable.
Adding a language? Drop in Strings.sv-SE.resx holding only the entries Swedish spells differently. A
culture file is an override list, not a copy.
That is the whole of the simple path.
| Guide | Read it for |
|---|---|
| Typed keys | Text that is an identity: giving a key its own type, and the set it is filed under. |
| Declaring a vocabulary | Every VocabularyResource setting, what gets generated, and the one non-obvious constraint. |
| Diagnostics | SL1001–SL1016: what each refuses, and which to make fatal. |
| Scope | What this package leaves to you, and why it ships a list formatter. |
The package icon is the "globe showing Europe-Africa" emoji from Google's Noto Emoji, used unmodified under the Apache License 2.0. It is licensed separately from the source code above — see THIRD-PARTY-NOTICES.md.
Changes are documented in CHANGELOG.md.
MIT.