samedi 31 juillet 2021

Building CSharp application with localization-aware language keys

Intro

I am looking for more customized solution for translating my app. I will be using Humanizer and Smart.Format after obtaining entries. The problem is to define keys to obtain them in the first place.

Requirements

The requirements are:

  1. Language keys must be defined in-code, preferably near place where they are used
  2. Language keys must contain default-English values
  3. All language keys must be listed (XML, CSV, JSON, anything) after building the app suite
  4. Language entries must be provided from external source (like JSON file), without the need for any kind of recompilation
  5. The app may contain multiple executables, shared libraries, etc. all of them in form of CSharp apps

Discarded solutions

First, the things I discarded:

  • Built-in CSharp Resources.dll; They violate (1) and (4)
  • External file with keys. Violates (1)

My idea for handling the problem

Now, my idea for the solution looks that way (and is inspired by C++ GetText)

There is a template class which contains keys:

private sealed class Module1Keys : LocalizationKeys<Module1Keys>
{
    public static readonly LocalizationKey HelloWorld = DefineKey("/foo", "Hello World!");
    public static readonly LocalizationKey HelloWorld2 = DefineKey("/bar", "Hello World2!");
}

And the class LocalizationKeys contains a static method that will actually register keys in simple collection

public abstract class LocalizationKeys<T> where T : LocalizationKeys<T>
{
    protected static LocalizationKey DefineKey(string path, string english)
    {
        var ret = new LocalizationKey(typeof(T), path, english);
        // Following registers localization key in runtime:
        Localization.Instance.RegisterLocalizableKey(ret);

        return ret;
    }
}

The only thing left to handle in this approach is to list localizable keys during build... which is where I had hit the wall. It is very easy to list them during runtime, but I cannot run the code on build time (particularly it may be built as shared library).

Maybe I am overthinking myself and there is better, more clean solution - I don't need to stick with this solution, but Googling around has not yielded anything better...

Aucun commentaire:

Enregistrer un commentaire