Имеется приложение, которое хостит ряд однотипных плагинов (MEF), каждый плагин работает с одной или двумя сетевыми службами у которых различаются числовые форматы и форматы времени. В дополнение к этому приложение пишет лог файлы, в которых выводит полученные от служб данные и в этих логах хочется получить единообразное отображение данных, при этом избавившись от необходимости указания правил форматирования при каждом вызове метода ToString().
Собственно проблем с этим нет, я реализовал для каждой службы свой экземпляр NumberFormatInfo и еще один дополнительный для отображения данных в логах. Но, возник вопрос, как правильнее всего перегружать стандартные значения ОС? Те я могу в контексте каждого плагина поменять значение у текущего потока следующим образом:
Здравствуйте, 3332560, Вы писали:
3>Собственно проблем с этим нет, я реализовал для каждой службы свой экземпляр NumberFormatInfo и еще один дополнительный для отображения данных в логах. Но, возник вопрос, как правильнее всего перегружать стандартные значения ОС?
Самый правильный способ — передавать культуру явно, тем более что MEF.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, 3332560, Вы писали:
S>Самый правильный способ — передавать культуру явно, тем более что MEF.
S>Если лень — обновиться на 4.6 и изменять CultureInfo.CurrentCulture. См секцию How a Thread's Culture Is Determined и пример в этой секции.
Я на 4.6
Но, проблема в том, что, мне не надо менять именно саму культуру... Наверное, я плохо описал свою ситуацию.
Плагин1 работает со службой1 и со службой2 (службы, это полностью не подвластные мне сторонние приложения). Работа происходит по средствам обращения к API службы. Для примера пуст обе службы отдают данные в формате англо язычной культуры, но у службы1 разделителем у дробных числе является точка, а у второй запятая (да это полностью не корректно, но вот у меня акая ситуация). И мне приходится по всему коду плагина управлять правилами форматирования строк и правилами преобразования чисел, что очень не удобно. Хочется получить простой способ контроля над этим делом, собственно для этого я создаю инстансы NumberFormatInfo персонально для каждой службы, вопрос, как правильнее ими воспользоваться для переопределения параметров языковой культуры. И стоит ли в таком случае создавать новые культуры для службы ?
3>Плагин1 работает со службой1 и со службой2 (службы, это полностью не подвластные мне сторонние приложения). Работа происходит по средствам обращения к API службы. Для примера пуст обе службы отдают данные в формате англо язычной культуры, но у службы1 разделителем у дробных числе является точка, а у второй запятая (да это полностью не корректно, но вот у меня акая ситуация).
// numberformatinfo.cspublic static NumberFormatInfo CurrentInfo {
get {
System.Globalization.CultureInfo culture = System.Threading.Thread.CurrentThread.CurrentCulture;
if (!culture.m_isInherited) {
NumberFormatInfo info = culture.numInfo;
if (info != null) {
return info;
}
}
return ((NumberFormatInfo)culture.GetFormat(typeof(NumberFormatInfo)));
}
}
Соответственно варианта два: или вы подменяете CurrentThread.CurrentCulture на время работы с каждой службой, или передаёте NumberFormatInfo явно для каждой форматируемой/разбираемой строки. После того как сделаете выбор, можно будет обсуждать конкретные варианты.
P.S. Передавать только NumberFormatInfo — путь к _очень_ интересным граблям. Подменяйте всю культуру целиком, так меньше шансов ошибиться.
S> // numberformatinfo.cs
S> public static NumberFormatInfo CurrentInfo {
S> get {
S> System.Globalization.CultureInfo culture = System.Threading.Thread.CurrentThread.CurrentCulture;
S> if (!culture.m_isInherited) {
S> NumberFormatInfo info = culture.numInfo;
S> if (info != null) {
S> return info;
S> }
S> }
S> return ((NumberFormatInfo)culture.GetFormat(typeof(NumberFormatInfo)));
S> }
S> }
S>
Я просмотрел приведенные вами участки кода до дыр, но я не вижу (не понимаю) "корня" проблемы. Вы хотите отметить плохой дизайн данных методов?
S>Соответственно варианта два: или вы подменяете CurrentThread.CurrentCulture на время работы с каждой службой, или передаёте NumberFormatInfo явно для каждой форматируемой/разбираемой строки. После того как сделаете выбор, можно будет обсуждать конкретные варианты.
S>P.S. Передавать только NumberFormatInfo — путь к _очень_ интересным граблям. Подменяйте всю культуру целиком, так меньше шансов ошибиться.
Я тоже склоняюсь к способу подмены значения свойства CurrentThread.CurrentCulture, мне будет это удобно и комфортно сделать, так как каждая служба работает в собственном потоке.
Я так же несколько раз перечитал данную статью с MSDN NumberFormatInfo, но по прежнему нахожусь в глубоком замешательстве как именно в моем случае стоит поступить наиболее правильно. Пока имеются лишь следующие идеи:
1. произвести наследование от "правильной" языковой культуры, для выше озвученного примера от en-US
2. в наследнике подменить значения NumberFormatInfo собственным экземпляром созданным через конструктор
3. аналогично поступить для DateTimeFormatInfo
4. подменить значение CurrentThread.CurrentCulture на культуру службы перед началом работы с ней
Но меня терзают куча сомнений. Хочется раз и навсегда разобраться для себя в данном вопросе и перестать избегать его. Спасибо.
Здравствуйте, 3332560, Вы писали:
3>Я просмотрел приведенные вами участки кода до дыр, но я не вижу (не понимаю) "корня" проблемы. Вы хотите отметить плохой дизайн данных методов?
Нет, при чём здесь дизайн? Намёк был про невозможность передать NumberInfo кроме как двумя перечисленными выше способами.
3>Я тоже склоняюсь к способу подмены значения свойства CurrentThread.CurrentCulture, мне будет это удобно и комфортно сделать, так как каждая служба работает в собственном потоке.
Как всегда для таких вещей: подменяем что-то глобальное — пишем тест на работоспособность вместе с тасками, await и тыды и тыпы. Вроде бы понятное правило, но тем не менее, на эти грабли наступают все по одному разу как минимум
Я это дело освежил буквально сегодня, успешнейше положив тесты на билдсервере
3>Я так же несколько раз перечитал данную статью с MSDN NumberFormatInfo, но по прежнему нахожусь в глубоком замешательстве как именно в моем случае стоит поступить наиболее правильно. Пока имеются лишь следующие идеи: