Исходники.Ру - Программирование
Исходники
Статьи
Книги и учебники
Скрипты
Новости RSS
Магазин программиста

Главная » Статьи по программированию » .NET - Framework »

Обсудить на форуме Обсудить на форуме

Как сделать использование текстовых ресурсов в .NET простым и надежным
В первую очередь, эта статья предназначена разработчикам программных компонентов для платформы .NET, поддерживающих интернационализацию. Статья будет полезна для всех, кто работает с .NET, используя файлы ресурсов и функции типа String.Format.
Для кого эта статья
Пример задачи, используемой для демонстрации
Решение от Microsoft
ResxWrap - как средство устранения подобных недостатков
Как сгенерировать обертку
Заглянем внутрь
Резюме
Исходники

Для кого эта статья

В первую очередь, эта статья предназначена разработчикам программных компонентов для платформы .NET, поддерживающих интернационализацию. Статья будет полезна для всех, кто работает с .NET, используя файлы ресурсов и функции типа String.Format.

Пример задачи, используемой для демонстрации

Мы имеем программу Windows Forms, которая должна поддерживать 3 языка: английский, итальянский и русский. В частности, в строке состояния программы должна выводиться строчка: "Дата: {текущее число}" на языке текущей локали пользователя.

Решение от Microsoft

Microsoft в таком случае рекомендует сделать следующее:

  1. Создать по одному .resx файлу для каждого из поддерживаемых языков для хранения строковых ресурсов.
  2. Добавить в каждый из этих файлов строчку с общим идентификатором ресурса, например "IDS_DATE", с текстом, соответствующим языку. Например, для английской версии, тект будет "Date: {0}".
  3. Написать примерно следующий код:
string messageTemplate = resourceManager.GetString( "IDS_DATE" );
string finalMessage = string.Format( messageTemplate, new DateTime() );
// Обновление текста в строке состояния

ПРИМЕЧАНИЕ
Казалось бы, все хорошо, но взглянем на этот код повнимательнее:

  1. Если изменить имя идентификатора в ресурсах или ошибиться в написании этого имени в коде, то компилятор не выдаст ошибки, т.к. в коде это имя записывается в виде строки.
  2. Зачастую строковые ресурсы - это шаблоны сообщений, содержащие несколько параметров, а т.к. сами шаблоны объявлены в другом файле, это создает дополнительный риск того, что количество или последовательность параметров при дальнейшем форматировании шаблона будут рассогласованны.

ResxWrap - как средство устранения подобных недостатков

Именно для решения этих проблем была создана утилита ResxWrap - генератор классов-оберток для текстовых ресурсов из .resx файлов. Классы-обертки предоставляют пользователю возможность работать с ресурсами в гораздо более удобной манере. Для вышеописанного примера достаточно написать:

string finalMassage = generatedWrapper.IDS_DATE( new DateTime() );
// Обновление текста в строке состояния

Что же изменилось?

  1. Вместо двух строчек кода мы имеем одну. Не так плохо сократить количество рутинного кода в два раза.
  2. Если название идентификатора изменится, теперь мы в безопасности, т.к. компилятор тут же выдаст ошибку, поскольку у класса-обертки больше не будет метода IDS_DATE.
  3. Если мы изменим количество аргументов в текстовом шаблоне "IDS_DATE", то тоже никаких проблем. Компилятор опять сообщит нам об ошибке - ведь сигнатура соответствующего метода класса-обертки изменится тоже.
  4. Редактируя вызов этого метода можно посмотреть справку по каждому параметру для уверенности, что порядок их следования правильный.

Как сгенерировать обертку

ResxWrap - утилита, управляемая параметрами командной строки. Возвращаясь к нашему примеру, допустим, что наш проект имеет пространство имен по умолчанию "SampleApp", файлы проекта находятся в директории "C:\My Projects\SampleApp", а файл ресурсов называется "StringTable.resx". Тогда, чтобы сгенерировать класс-обертку достаточно запустить генератор со следующими параметрами:

ResxWrap SampleApp "C:\My Projects\SampleApp\" StringTable

При завершении генерации в директории проекта появится новый файл с именем "__StringTable.cs", который будет содержать определение одноименнного класса описанного в том же пространстве имен.

Конечно можно создать .bat файл и каждый раз при изменении в "StringTable.resx" запускать генератор вновь, но для надежности лучше добавить одну строчку в Pre-build Event Command Line в настройках проекта. Для этого достаточно написать в случае нашего примера следующее:

ResxWrap SampleApp $(ProjectDir) StringTable

Заглянем внутрь

Сгенерированный класс содержит:

  • конструктор, в котором происходит инициализация экземпляра защищенного поля типа System.Resources.ResourceManager;
  • доступные только для чтения статические поля, с именема для каждого идентификатора ресурса, объявленного в .resx файле;
  • методы и доступное только для чтения свойства, возвращающие текстовое значение для каждого ресурса.

Если текстовая строка содержит параметры, то сигнатура метода будет содержать соответствующее количество параметров, сопровожденных комментариями, а тело метода, помимо загрузки шаблона текстового сообщения, будет также содержать вызов String.Format, готовящий финальную версию сообщения.

Резюме

Итак, если вы решили использовать утилиту ResxWrap при разработке проекта, вам нужно:

  1. добавить вызов утилиты ResxWrap в файл проекта;
  2. перекомпилировать проект;
  3. добавить сгенеренный файл класса-обертки в список файлов проекта;
  4. создать экземляр класса-оберки;
  5. вызвать соответствующий метод или свойство для извлечения нужных текстовых ресурсов.

Исходники

Проект CRL Resource Wrapper разрабатывается в рамках движения Open Source. Утилита ResxWrap доступна для свободного скачивания по следующему адресу: http://sourceforge.net/project/showfiles.php?group_id=98011&package_id=104991.


Может пригодится:


Автор: Yury Fedorov, Bisoft Ltd.
Прочитано: 3542
Рейтинг:
Оценить: 1 2 3 4 5

Комментарии: (0)

Добавить комментарий
Ваше имя*:
Ваш email:
URL Вашего сайта:
Ваш комментарий*:
Код безопастности*:

Рассылка новостей
Рейтинги
© 2007, Программирование Исходники.Ру