Nov 24, 2009

Локализация веб приложений

.net предоставляет отличные возможности по локализации приложений. Средства мощные и достаточно удобные в большинстве сценариев, но есть некоторые вещи, которые мешают мне в каждом приложении:

  1. Если использовать локальные ресурсы, то получение строки из них будет следующим: this.GetLocalResourceObject(“Key”); С этой записью есть следующие проблемы:

    • Этот метод возвращает Object, соответственно чтобы получить строку из этой и без того громоздкой записи необходимо написать GetLocalResourceObject(“Key”).ToString();
    • Поскольку метод возвращает Object, то при отсутствии соответствующего ключа в файлах ресурсов он возвращает Null. И узнаете Вы об этом Null только в момент выполнения (и то если вызовете ToString(), чаще же используется запись <%= GetLocalResourceObject(“Key”) %> которая просто ничего не выводит).

    Причиной этих проблем можно назвать отсутствие автоматической генерации кода. Для папки AppGlobalResources у каждого resx файла есть так же Designer.cs файл, в котом создается класс предоставляющий доступ к каждой строке. Этот класс решает проблемы отсутствующих ключей и обеспечивает intellysence решая в общем то все указанные проблемы. 

  2. Использование глобальных ресурсов. Глобальные ресурсы лишены недостатков локальных, но есть одна проблемка: невозможность разложить ресурсы по папкам и пространствам имен. Чем больше проект, тем больше строк в ресурсах, тем больше файлов. Со временем папка AppGlobalResources превращается в огромный склад, в котором довольно сложно что-либо найти. При этом генератор кода раскладывает классы вне зависимости от папок, в которых они лежат, просто в пространство имен Resources.

  3. И последняя, хотя пожалуй наиболее важная проблема. Если необходимо получить локализованную строку не в веб части проекта. Например:

    Наследование с названием типа объекта

    Есть абстрактный класс Role с абстрактным свойством DisplayName. Это очень удобно когда в интерфейсе необходимо показывать какие роли привязаны к пользователю. Обычно такие классы будут находится в модуле бизнес логики, которая не может содержать ссылки на веб приложение.

Решением этих проблем может быть размещение ресурсов в отдельной сборке, на которую можно добавить ссылки из всех частей приложения. В этом проекте можно добавить файл ресурсов, и студия будет генерировать .Designer.cs файлы.

Но в реализации по умолчанию есть одна важная проблема – классы помечены как internal. Можно конечно изменить код вручную, но при сохранении файла .resx генератор будет запущен заново, и отменит все изменения сделанные вручную.

Я собирался написать шаблоны с использованием t4Toolbox, но поискав чуть чуть, оказалось что велосипед уже изобретен. В данной статье все довольно четко расписано, и проблем с использованием быть не должно. Данный генератор раскладывает генерируемые файлы по пространствам имен согласно структуре папок и сгенерированные классы помечены как public, а так же другие полезные фичи.

No comments:

Post a Comment