-
-
Notifications
You must be signed in to change notification settings - Fork 0
Getting started
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).
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 |
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.
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.
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 Studiothe option is called C# analyzer additional file
In
Riderthe option is calledAdditionalFiles
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.
TODO: No Nuget packages exist yet
Nevertheless, you need to reference the following libraries:
- Localization.Shared
- Localization.Generator
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.
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:
- You are using the default
Translatortype - you can create your own implementation if needed - You are using CommunityToolkit.MVVM and its
Iocsystem 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:
- Registering DI services including
TranslatorasITranslator - Configuring
Iocwith the registered DI services collection - Initializing the
CultureManager- the singleton class for managing the current language of the application - Registering the translation provider from the shared library into the translator
See here on how to load all translation providers in a single line.
Reference the Localization.WPF library.