Skip to content

Getting started

Denis Akopjan edited this page Jul 10, 2025 · 3 revisions

What is this library for?

NETLocalization allows you to define a list of translated strings and easily wire them up to your WPF, Avalonia, .NET Maui (and potentially other) UI applications with ease. What's more, it allows you to change the language of the application in real time!

The library utilizes source generators (without reflection); thus, it opens doors for better performance and the utilization of AOT (e.g., Avalonia supports AOT).

What do I need?

You need to have at least Visual Studio Version 17.14.8 for the source generators to work - the library relies on the following NuGets to work:

NuGet Version
Microsoft.CodeAnalysis.CSharp 4.14.0
Microsoft.CodeAnalysis.Analyzers 4.14.0

How do I create my localizations?

You can add localizations into a *.csproj that:

  • will be shared between multiple projects, or
  • is your UI application, or
  • is some business logic library.

You are not limited by where you store your localizations.

Let's assume that you'd like to have a shared localization project.

Creating a shared localization project

You can create a project with the target framework set to netstandard2.0, net8.0 and higher, or (not tested) the old-school net4.8. Ensure that the project is configured to use the latest C# version.

The source of the localizations

Create an XML file within your project, and add your translations in the following format:

<?xml version="1.0" encoding="utf-8"?>
<translations namespace="MyLocalizations">
  <set key="Cat" description="Neutral name of the animal - cat">
    <item lang="en">Cat</item>
    <item lang="de-de">Katze</item>
  </set>
  <set key="Dog" description="Neutral name of the animal - dog">
    <item lang="en">Dog</item>
    <item lang="de-de">Hund</item>
  </set>
</translations>
The XML must follow the defined XSD schema:
 <?xml version="1.0" encoding="UTF-8" ?>
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xs:element name="translations">
     <xs:complexType>
       <xs:sequence>
         <xs:element name="set" maxOccurs="unbounded">
           <xs:complexType>
             <xs:sequence>
               <xs:element name="item" minOccurs="1" maxOccurs="unbounded">
                 <xs:complexType>
                   <xs:simpleContent>
                     <xs:extension base="xs:string">
                       <xs:attribute name="lang" use="required">
                         <xs:simpleType>
                           <xs:restriction base="xs:string"/>
                         </xs:simpleType>
                       </xs:attribute>
                     </xs:extension>
                   </xs:simpleContent>
                 </xs:complexType>
               </xs:element>
             </xs:sequence>
             <xs:attribute name="key" type="xs:string" use="required" />
             <xs:attribute name="description" type="xs:string" use="required" />
           </xs:complexType>
         </xs:element>
       </xs:sequence>
       <xs:attribute name="namespace" type="xs:string" use="required" />
     </xs:complexType>
   </xs:element>
 </xs:schema>

Edit the properties of the file and configure it to be an AdditionalFiles.

In Visual Studio the option is called C# analyzer additional file

In Rider the option is called AdditionalFiles

If you are not using .NET Framework and have a modern SDK-style project, then the file should be included in the *.csproj like so:

<ItemGroup>
    <AdditionalFiles Include="MyLocalizations.xml" />
</ItemGroup>

Note: there might be <None Include="MyLocalizations.xml" /> - that can be safely removed.

Add the dependencies

TODO: No Nuget packages exist yet

Nevertheless, you need to reference the following libraries:

  • Localization.Shared
  • Localization.Generator

The provider of the localizations

Next, create a C# class file called *Provider.cs, where * is the name of your XML localization file.

Note: You can name the class and file as you wish; no reflection or IL weaving magic is being done. This is recommended for a cleaner implementation.

Now, decorate that class with the TranslationProvider attribute and specify the name of the XML in the round braces.

Here's how it should look:

[TranslationProvider("MyLocalizations")]
public static partial class MyLocalizationsProvider
{
}

Assuming you are running on the latest C# version and not using the .NET Standard 2.0 SDK, you can simplify this even further to:

[TranslationProvider("MyLocalizations")]
public static partial class MyLocalizationsProvider;

The source generators should kick-in and the partial keyword will light up. See what has been generated by clicking on the class name, MyLocalizationsProvider, and pressing F12 to reveal the magic.

How do I access the defined localizations?

Accessing the localizations requires referencing a specific NuGet package for your UI framework. The following are the correctly supported frameworks:

  • WPF
  • Avalonia
  • .NET MAUI

Regardless of which UI framework you are using, the first step is always to register the ITranslator in your DI service. The examples will assume two things:

  1. You are using the default Translator type - you can create your own implementation if needed
  2. You are using CommunityToolkit.MVVM and its Ioc system for DI

In the relevant location of your UI app (e.g., for WPF it's App.xaml.cs), execute the following code:

var serviceCollection = new ServiceCollection();
serviceCollection
    // ... Your other DI service registrations
    .AddSingleton<ITranslator, Translator>();
Ioc.Default.ConfigureServices(serviceCollection.BuildServiceProvider());

CultureManager.Initialize(Ioc.Default);

var translator = Ioc.Default.GetRequiredService<ITranslator>();
translator.RegisterTranslations(MyLocalizationsProvider.GetTranslations());

This code is doing the following:

  1. Registering DI services including Translator as ITranslator
  2. Configuring Ioc with the registered DI services collection
  3. Initializing the CultureManager - the singleton class for managing the current language of the application
  4. Registering the translation provider from the shared library into the translator

See here on how to load all translation providers in a single line.

WPF

Reference the Localization.WPF library.

Clone this wiki locally