Простая локализация .NET приложений с помощью Slang.Net

Привет! Меня зовут Егор, я работаю в компании DD Planet. В статье я хочу поделиться знаниями о том, как быстро и легко локализовать .NET-приложение с помощью собственного решения для локализации — Slang.Net.
Введение
Когда я только начинал свой путь как .NET-разработчик, локализация приложений казалась вполне понятной задачей. Стандартные механизмы — resx-файлы и связанные с ними сервисы — справлялись со своей работой, и тогда я даже не задумывался о том, что может быть иначе. Однако все изменилось, когда я переключился на разработку Flutter-приложений.
В этом новом для меня мире я открыл slang — инструмент для работы с локализацией, который существенно упростил рутину, связанную с поддержкой нескольких языков. Когда я вернулся к .NET-разработке, мой взгляд на стандартные механизмы локализации изменился. Простота и удобство, которые я нашел в slang, заставили меня осознать, насколько сложными и громоздкими кажутся resx-файлы по сравнению с этим инструментом.
Дальнейшие размышления привели меня к идее создать порт slang для .NET, адаптированный под особенности платформы.
Что такое Slang.Net?
Slang.Net — порт библиотеки slang из сообщества Dart/Flutter для .NET, предоставляющей типобезопасный и удобный способ работы с переводами в приложении. Порт дополнен новыми возможностями, включая форматирование строк, которое отсутствовало в оригинальной версии библиотеки на момент портирования, но было добавлено в одном из последних обновлений.
Основные возможности
- Типобезопасность: Генерирует строго типизированный код для работы с переводами;
- Поддержка форматирования: Встроенная поддержка форматирования строк и параметров;
- Плюрализация: Автоматическая обработка множественных форм слов в зависимости от их количества;
- Интеграция с GPT: Использование GPT-модели для автоматического перевода строк.
- Гибкость: Поддержка списков, словарей и вложенных структур переводов;
- Удобство: Простая интеграция и использование в проекте. Поддержка иерархического представления для строк локалей. Например, можно заложить иерархию по фичам и контроллерам — так, как вам удобнее.
Быстрый старт
Шаг 1: Установка пакета
Установите Slang.Net

Шаг 2: Добавление JSON-файлов с переводами
Добавьте json файл для локали по умолчанию. Можно положить в любую папку проекта, для примера, положим его в папку “i18n”:
- strings_ru.i18n.json
Названия файлов должны иметь следующий вид:
<название>_<культура>.i18n.json
Культура представлена в привычной форме кода языка, с указанием или без указания кода страны (“ru”, “en-US””). Для файла локализации по умолчанию культуру можно не указывать.
Пример содержимого strings_ru.i18n.json:

Шаг 3: Конфигурация Slang.Net
Создайте файл slang.json в корне проекта:

Шаг 4: Включение файлов в проект
Добавьте следующие строки в ваш .csproj файл:

Файлы с типом сборки AdditionalFiles используются анализаторами и генераторами кода и не встраиваются в итоговую сборку проекта.
Шаг 5: Создание partial класса для переводов
Создайте класс с любым названием для доступа к строкам локализации, например, Strings.
В InputFileName указываем префикс из названия json файлов, на основе которых будет генерация для этого класса.

Можно добавить геттер для быстрого доступа к рутовому узлу словаря локализации

Шаг 6: Использование в вашем коде
После генерации кода вы можете использовать переводы следующим образом:

Расширенные возможности
Интерполяция строк
Slang.Net поддерживает интерполяцию и типизацию параметров:

В коде:

По умолчанию тип параметра object. Так же есть более сложный синтаксис установки типов параметров:

Установка отдельного словаря с префиксом @ позволяет использовать еще несколько фич библиотеки, о которых пойдет речь ниже.
Поддержка склонений с числительными (Pluralization)
Обработка множественных форм слов в зависимости от количества:

В коде:

Доступны следующие ключи для работы данной фичи: zero, one, two, few, many, other.
По умолчанию имя параметра n, его можно поменять на свой с помощью param:

Имя параметра по умолчанию можно переопределить, используя параметр PluralParameter в атрибуте TranslationsAttribute:

Форматирование строк
Поддержка форматирования дат и чисел. Можно использовать следующие типы с поддержкой форматирования в ToString(string format) - int, long, double, decimal, float, DateTime, DateOnly, TimeOnly, TimeSpan. Для остальных типов используется метод string.Format(format, cultureInfo).

В коде:

Комментарии в переводах
Вы можете добавлять комментарии в JSON-файлы, которые будут включены в сгенерированный код:

Тогда сгенерированный код будет включать в себя переопределенный xml комментарий. По умолчанию комментарий включает в себя содержимое строки локализации.

Ссылки на другие переводы
Slang.Net поддерживает ссылки на другие строки перевода с помощью @::

В коде:

Путь на локаль должен быть абсолютным относительно рутового объекта дерева с локалями.
Использование списков и словарей
Slang.Net поддерживает списки и словари:

В коде:

Перевод с помощью GPT
Одной из уникальных возможностей Slang.Net является интеграция с моделями GPT для автоматического перевода строк. Эта функция особенно полезна, когда вам нужно быстро локализовать приложение на несколько языков. Для перевода достаточно указать код культуры для перевода, и инструмент сам создаст файл локализации для новой локали или обновит существующий. В настоящее время поддерживается только OpenAI API.
Установка slang-gpt-cli
Для начала установите CLI утилиту с помощью команды:

Настройка конфигурации
Создайте или отредактируйте файл slang.json и добавьте следующую конфигурацию:

Тип модели и описание проекта являются обязательными параметрами для старта перевода.
Запуск перевода
Выполните команду для перевода:

Где:
- <csproj> — путь к вашему проекту .NET. Если параметр --project не задан, будет использоваться первый найденный csproj файл проекта в текущей директории.
- <api-key> — ваш API-ключ OpenAI.
- <culture> — двухбуквенный код культуры, перевод на которую вы хотите получить. Если --target не задан, будут использоваться культуры уже существующих файлов локализации.
Чтобы выполнить полный перевод базовой локали с перезаписью текущих локалей (если файл целевых локалей уже существует), укажите аргумент --full.
Для исключения отдельных ключей из перевода используйте модификатор ignoreGpt:

Список поддерживаемых моделей которые можно указать в slang.json следующий:

Примечание: 1k токенов ≈ 750 слов на английском языке.
Преимущества использования GPT:
- Скорость: Автоматический перевод большого количества строк за короткое время
- Наличие контекста: GPT-модели учитывают контекст, что повышает качество перевода
- Экономия ресурсов: Сокращение затрат на ручной перевод
Интеграция с различными платформами
Slang.Net не зависит от конкретной платформы и может использоваться в:
- Консольных приложениях;
- WPF-приложениях;
- ASP.NET Core приложениях (включая фронтенд: Blazor, MVC);
- Xamarin и MAUI приложениях.
Локализация Web Api
Для установки поддерживаемых культур можно воспользоваться свойством SupportedCultures и BaseCulture:

Осталось подключить middleware, который переключает культуру в зависимости от значения в хедере Accept-Language.

Локализация AvaloniaUI
Рекомендуется устанавливать строки в XAML через Bindings для переключения локализации в рантайме (без необходимости перезапускать приложение).

Instance поддерживает интерфейс INotifyPropertyChanged для уведомления UI о изменении свойства Root.
Для переключения языка можно воспользоваться методом SetCulture.
Для использования локали с параметрами через xaml нужно использовать MultiValueConverter, передавая в параметры Instance и параметры локали.
Например, локаль с параметрами задана следующим образом:

Тогда ее применение в xaml будет выглядеть следующим образом:

Где SelectedCount - свойство ViewModel.
Конвертер будет выглядеть следующим образом:

В последних версиях C# (с 11 версии) данный код можно упростить до:

Таким образом, при смене языка через метод Strings.SetCulture, текст автоматически поменяется в интерфейсе на текст выбранной культуры. Именно поэтому не рекомендуется использовать тексты локализации внутри ViewModel, только если это не текстовки каких-либо диалоговых окон, которые обычно не отображаются в момент смены языка.
Заключение
Slang.Net — инструмент для локализации .NET-приложений, который:
- Упрощает работу с переводами;
- Делает код чище и понятнее;
- Позволяет автоматически переводить строки на разные языки благодаря интеграции с GPT;
- Экономит время и ресурсы.
Если вы ищете решение для поддержки нескольких языков в вашем приложении, Slang.Net — отличный выбор. В статье я кратко описал возможности библиотеки. Дополнительные параметры и флаги вы найдете в файле документации репозитория, где также можно посмотреть примеры их использования.
Полезные ссылки: