Блок приложения для валидации корпоративных библиотек и интернационализация - PullRequest
5 голосов
/ 04 августа 2010

Сценарий

Настольное приложение .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 () для валидатора EnterpriseLibrary, сообщения валидации уже локализованы на французский, и у вас нет возможности записать их, например, в файл журнала на английском языке.

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

Есть идеи, как внедрить подобный механизм в блок валидации Enterprise Library?Пока что есть идеи:

  • Временное переключение CurrentCulture (мне это не нравится, и это решает только половину проблемы)
  • Исправление блока проверки библиотеки предприятия (мне не нравитсяэто тоже)

Спасибо за вашу помощь и поделились идеями!

1 Ответ

4 голосов
/ 08 августа 2010

Когда у нас было требование к отложенному разрешению ресурсов, мы отказались от использования MessageTemplateResourceName и вместо этого поместили наш идентификатор ресурса в качестве свойства MessageTemplate.Затем мы используем этот идентификатор позже, чтобы найти значение строки ресурса, используя текущую культуру.

Мы стандартизировали соглашение об именах для id примерно так: 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 и создания классов сообщений с необходимой вам информацией.

...