NTDLS.Localization 1.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package NTDLS.Localization --version 1.0.1
                    
NuGet\Install-Package NTDLS.Localization -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NTDLS.Localization" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NTDLS.Localization" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="NTDLS.Localization" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add NTDLS.Localization --version 1.0.1
                    
#r "nuget: NTDLS.Localization, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package NTDLS.Localization@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=NTDLS.Localization&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=NTDLS.Localization&version=1.0.1
                    
Install as a Cake Tool

NTDLS.Localization

Localization from a SQLite translation database. The English text in the source code is the key, so an untranslated phrase (or a missing database) simply shows in English.

The database

A SQLite file, Translations\Translations.db next to the program, with one table:

Translation
    TranslationId  INTEGER PRIMARY KEY
    Phrase   TEXT NOT NULL UNIQUE COLLATE NOCASE   -- the English phrase as written in the code: the key
    de, fr, ja, zh-Hans, pt-BR, ...  TEXT          -- one column per language, named by its culture code; empty means "not translated yet"
    LastModified  TEXT                             -- when the row was last changed (UTC, yyyy-MM-dd HH:mm:ss); not used when looking up

The row id column is not called Id because SQLite column names are not case sensitive and id is the code for Indonesian.

Columns are named by the culture code, exactly as .NET writes it (de, zh-Hans, pt-BR). A regional culture uses its language's column unless it has a column of its own (de-AT uses de; plain Norwegian no uses nb). Databases whose columns still have the older language names ("German", "Chinese simplified") and a key column still called English are read too; LocalizerScan renames them to codes the next time it runs. Each language is read once, the first time it is needed, and then served from memory. The file is only ever read, never locked or changed.

Copy it to the output folder from the project:

<ItemGroup>
  <None Include="Translations\Translations.db" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

Using it

using NTDLS.Localization;

Localizer.Default.SetLanguage("de");          // "de", "pt-BR", or empty / "auto" to follow Windows

Text = Localizer.Default.Localize("Search");
MessageBox.Show(Localizer.Default.Localize("Copied {0} files to {1}", count, folder));

Use a format string with {0}, {1} for text that has values in it (not $"..." or +), so translators get the whole sentence. The translation must keep the same placeholders; if it does not, the English text is used.

To write just Localize("Search"), add a global using for the static helper to the project:

<ItemGroup>
  <Using Include="NTDLS.Localization.StaticLocalizer" Static="true" />
</ItemGroup>

Passing it to other libraries: ILocalizer

A library that shows text takes an ILocalizer, so it does not care how the application stores translations:

public class MyLibrary(ILocalizer? localizer = null)
{
    private readonly ILocalizer _localizer = localizer ?? NullLocalizer.Instance;

    public string Describe(int count) => _localizer.Localize("Found {0} items", count);
}

var library = new MyLibrary(Localizer.Default);

NullLocalizer.Instance returns the English text, for libraries used without a localizer and for tests.

Windows Forms (the net10.0-windows build)

FormLocalizer translates the text the designer put on a form: titles, labels, buttons, check boxes, group boxes, tab pages, menus, list columns and text box placeholders. The designer's text is the phrase, so designer code needs no Localize(...) calls.

public FormMain()
{
    InitializeComponent();
    FormLocalizer.Apply(this);          // call again after changing the language
}

The designer's original text is remembered, so the form is translated from English each time. Text that the code set itself is left alone, so the form must update that itself.

Logging

The package writes no log. To see its warnings (a missing database, a broken placeholder), set:

LocalizationDiagnostics.OnWarning = (message, exception) => Log.Warning(message, exception);
LocalizationDiagnostics.OnError = (message, exception) => Log.Error(message, exception);

Adding phrases

A scanner that reads Localize("...") calls and the designer files, adds the new phrases to the database and translates the empty cells is LocalizerScan in the FinderSeeker repository.

Product 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.  net8.0-windows7.0 is compatible.  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.  net9.0-windows7.0 is compatible.  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-windows7.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 82 10/18/2026
1.0.1 88 10/17/2026
1.0.0 84 10/17/2026