Блок приложения для валидации корпоративных библиотек и интернационализация
сценарий
Настольное приложение.NET/WPF должно быть локализовано (или в терминах MS глобализировано) на язык, отличный от английского. То есть пользовательский интерфейс должен быть полностью адаптирован (метки, значки, ...).
Однако записи файла журнала, записи журнала аудита и другие выходные данные приложения должны оставаться на английском языке, чтобы англоязычный персонал службы поддержки мог их просмотреть. Они не говорят по-французски или по-китайски.
Приложение использует файлы RESX для выполнения локализации.
Блок проверки библиотеки предприятия используется для проверки бизнес-правил в объектной модели.
Теперь предположим, что существует служба, которая проверяет свои заданные аргументы объектной модели до выполнения реальной бизнес-логики. При некоторых обстоятельствах он получает недопустимые аргументы объектной модели, но продолжает выполнение с максимальным усилием. Предоставление недопустимых данных объектной модели, однако, должно быть зарегистрировано в журнале аудита и в файле журнала.
Пример услуги с использованием блока проверки.
public class Service : IService
{
public void MyMethod(MyObjectModelObject obj)
{
Validator validator = ValidationFactory.CreateValidator(typeof(MyObjectModelObject));
ValidationResults results = validator.Validate(this);
// !!! The messages in the validation results are now already localized to CurrentCulture.
// ... build a log message: msg
if (results.Count > 0)
{
Logger.Log(msg);
}
}
}
Как указано в комментарии к коду, когда вы вызываете Validate() для валидатора Enterprise Library, сообщения валидации уже локализованы на французский, и у вас нет шансов записать их, например, в файл журнала на английском языке.
В других областях нашего приложения мы используем класс сообщений, который инкапсулирует идентификатор ресурса и параметры, пока мы не уверены, в какой культуре мы хотим использовать разрешение фактического строкового значения. Вы можете назвать это отложенным разрешением ресурса.
Есть идеи, как внедрить подобный механизм в блок валидации Enterprise Library? Идеи пока что:
- Временное переключение CurrentCulture (мне это не нравится, и это решает только половину проблемы)
- Патч блока проверки библиотеки предприятия (мне это тоже не нравится)
Спасибо за вашу помощь и поделились идеями!
1 ответ
Когда у нас было требование отсроченного разрешения ресурсов, мы отказались от использования MessageTemplateResourceName
и вместо этого поместите наш идентификатор ресурса в качестве MessageTemplate
имущество. Затем мы используем этот идентификатор позже, чтобы найти значение строки ресурса, используя текущую культуру.
Мы стандартизировали соглашение об именах для идентификатора примерно так: RULESET_RULESETQUALIFIER_OPERATION_OBJECT_PROPERTY_VALIDATIONTYPE
, например RULESET_BMW_INSERT_CAR_YEAR_RANGE
или же RULESET_BMW_UPDATE_CAR_COLOR_LENGTH
и т.п.
В конфигурации VAB это будет выглядеть примерно так:
<property name="Color">
<validator lowerBound="0" lowerBoundType="Ignore" upperBound="50"
upperBoundType="Inclusive" negated="false" messageTemplate="RULESET_BMW_INSERT_CAR_COLOR_LENGTH"
messageTemplateResourceName="" messageTemplateResourceType=""
tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.StringLengthValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="String Length Validator" />
</property>
Основным недостатком является то, что вы теряете возможность легко использовать токены шаблонов сообщений, чтобы сделать сообщение слегка динамичным. Это может быть выполнено, но значения токенов должны быть где-то сохранены (например, ваш класс сообщений), чтобы они могли быть заменены позже при оценке строки сообщения.
Вы также можете рассмотреть возможность создания нескольких файлов ресурсов для каждой аудитории, для которой предназначены сообщения. То есть один ресурс для пользовательских сообщений и один для технических сообщений. Таким образом, вы можете иметь UserMessages.resources, UserMessages.fr-BE.resources для пользовательских сообщений. Затем в другом файле ресурсов продублируйте идентификаторы с другими сообщениями для регистрации (LogMessages.resources). Таким образом, вы можете получить дополнительную техническую информацию для сообщения журнала. Это может быть излишним, хотя.
Затем мы получаем доступ к строковым значениям, используя ResourceManager
:
ResourceManager userResourceManager =
new ResourceManager("UserMessages", Assembly.GetExecutingAssembly());
string userMessage = userResourceManager.GetString(resourceId);
ResourceManager logResourceManager =
new ResourceManager("LogMessages", Assembly.GetExecutingAssembly());
// Can also try to use InvariantCulture instead of "en"
string messageToLog = logResourceManager.GetString(resourceId, new CultureInfo("en"));
//alternative to ensure you get the english user message value:
// string messageToLog = userResourceManager.GetString(resourceId, new CultureInfo("en"));
Вы можете абстрагировать это в вспомогательный класс или добавить его в свой класс сообщений. Вам также может понадобиться создать некоторый код для извлечения ValidationResults и создания классов сообщений с необходимой вам информацией.