Когда компилил Rotor меня порозило то, что для компиляции надо поставить Perl.
Оказывается в Framework Microsoft решает эту проблему следующим образом.
Есть файл resource.txt со строками
...
Arg_IndexOutOfRangeException = Index was outside the bounds of the array.
Arg_NotSupportedException = Specified method is not supported.
...
На основе этого файла при помощи perl script генерится класс
//------------------------------------------------------------------------------
// This file is autogenerated by gensr.pl utilitity. Do not modify.
//------------------------------------------------------------------------------namespace MyNameSpace {
using System;
using System.Reflection;
using System.Globalization;
using System.Resources;
using System.Text;
using System.Threading;
using System.ComponentModel;
/// <summary>
/// AutoGenerated resource class. Usage:
///
/// string s = StrR.GetString(StrR.m_MyIdenfitier);
/// OR
/// string s = StrR.MyIdenfitier;
///
/// </summary>internal sealed class SR {
static SR loader = null;
static CultureInfo info = Thread.CurrentThread.CurrentCulture;
ResourceManager resources;
...
internal const string Arg_IndexOutOfRangeException = "Arg_IndexOutOfRangeException";
internal const string Arg_NotSupportedException = "Arg_NotSupportedException";
...
private SR() {
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
resources = new System.Resources.ResourceManager("MyNameSpace.resource", this.GetType().Module.Assembly);
}
private static SR GetLoader() {
if (loader == null) {
lock(typeof(SR)) {
if (loader == null) {
loader = new SR();
}
}
}
return loader;
}
public static string GetString(string name, params object[] args) {
// null CultureInfo: let ResouceManager determine the culturereturn GetString(info, name, args);
}
public static string GetString(CultureInfo culture, string name, params object[] args) {
SR sys = GetLoader();
if (sys == null)
return null;
string res = sys.resources.GetString(name, culture);
if (args != null && args.Length > 0) {
return String.Format(res, args);
}
else {
return res;
}
}
public static string GetString(string name) {
return GetString(info, name);
}
public static string GetString(CultureInfo culture, string name) {
SR sys = GetLoader();
if (sys == null)
return null;
return sys.resources.GetString(name, culture);
}
public static bool GetBoolean(string name) {
return GetBoolean(name);
}
public static bool GetBoolean(CultureInfo culture, string name) {
bool val = false;
SR sys = GetLoader();
if (sys != null) {
object res = sys.resources.GetObject(name, culture);
if (res is bool) {
val = (bool)res;
}
}
return val;
}
.....
}
}
Я конечно же не стал изобретать велосипед, немного подточил gensr.pl что бы генерил более удобный для использования класс SR, но все же не покидует душу вопрос — Неужели нет другого механизма или способа для локализации кода????
VP>Я конечно же не стал изобретать велосипед, немного подточил gensr.pl что бы генерил более удобный для использования класс SR, но все же не покидует душу вопрос — Неужели нет другого механизма или способа для локализации кода????
в принципе этот — самый нормальный
но можно и извратиться :)
создать локализованную форму с кучей лейблов и юзать ее:
Здравствуйте, V.Petrovski, Вы писали:
VP>По поводу визуальной части вроде все ясно VP>1. Ставишь свойство Localizable в true VP>2. Выбираешь нужный Language и локализуешь
VP>А вот как по поводу таких вещей
VP> MessageBox.Show("Unknown error "+ex.Message);
Посмотри на класс ResourceManager. Подробности можешь углядеть в исходниках януса.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, V.Petrovski, Вы писали:
VP>>По поводу визуальной части вроде все ясно VP>>1. Ставишь свойство Localizable в true VP>>2. Выбираешь нужный Language и локализуешь
VP>>А вот как по поводу таких вещей
VP>> MessageBox.Show("Unknown error "+ex.Message);
AVK>Посмотри на класс ResourceManager. Подробности можешь углядеть в исходниках януса.
//------------------------------------------------------------------------------
// This file is autogenerated by gensr.pl utilitity. Do not modify.
//------------------------------------------------------------------------------
...
internal sealed class SR {
static SR loader = null;
static CultureInfo info = Thread.CurrentThread.CurrentCulture;
ResourceManager resources;
...
В конечном итоге все managed ресурсы получаются через класс ResourceManager,
я про то, как проще создать продукт поддерживающий локализацию. Если использовать только голый ResourceManager возникают проблемы (неудобства):
1. Где его создать и когда??? (ну это не очень мощная проблема, но новичка загоняет)
2. Где хранить ключи для получения ресурсов??? (GetString(key))
3. Как быть когда ключы изменяются, добавляются и удаляются??? (менять константы в коде — copy+paste)
4. Как сдержать нервы после первых трех пунктов?? (это все рутина которую разработчик пытается устранить написав генерилку)
Здравствуйте, V.Petrovski, Вы писали:
VP>1. Где его создать и когда???
Синглтон с кешем RM'ов
VP>(ну это не очень мощная проблема, но новичка загоняет)
Значит надо поскорее переставать быть новичком.
VP>2. Где хранить ключи для получения ресурсов??? (GetString(key))
Что значит хранить? Прямо в коде, использующем эти ресурсы.
VP>3. Как быть когда ключы изменяются, добавляются и удаляются??? (менять константы в коде — copy+paste)
Ключи на то они и ключи, что меняются редко. Это практически имена переменных.
VP>4. Как сдержать нервы после первых трех пунктов?? (это все рутина которую разработчик пытается устранить написав генерилку)
Ты меня измени, но у меня такой чувство что ты болен юношеским максимализмом..
На этом мы и занкончим...
Я давно уже не новичок в нете (это так к сведению).
Я тебе могу привести кучу примеров когда ты один пишешь весь код у тебя все нормально, только потому, что ты один. А вот когда приходят (пи пи пи) зеленые, вот они горазды на такие выдумки, что ты себе предсавить не сможешь. Так вот по этой причине и раждаются runtime ошибки. Только по тому что, один заюзал константу а второй её в русурсном файле изменил. В таких случаях на этапе компиляции такие ошибки не словишь.
Здравствуйте, V.Petrovski, Вы писали:
VP>Здравствуйте, AndrewVK, Вы писали:
VP>Ты меня измени, но у меня такой чувство что ты болен юношеским максимализмом.. VP>На этом мы и занкончим... VP>Я давно уже не новичок в нете (это так к сведению).
VP>Я тебе могу привести кучу примеров когда ты один пишешь весь код у тебя все нормально, только потому, что ты один. А вот когда приходят (пи пи пи) зеленые, вот они горазды на такие выдумки, что ты себе предсавить не сможешь. Так вот по этой причине и раждаются runtime ошибки. Только по тому что, один заюзал константу а второй её в русурсном файле изменил. В таких случаях на этапе компиляции такие ошибки не словишь.
Что-то я вообще ничего не понимаю. Каким образом ты собираешься считывать данные в константу из ресурсов? И что конкретно ты в ресурсах хранишь — откуда рантайм ошибки? Ресурсы в первую очередь предназначены для хранения локализуемых стрингов. И что это за пи-пи-пи зеленые, которые у тебя в ресурсы лезут? Они что по совместительству и специалисты по языкам?
После долгих раздумий (с пару месяцев), предложу несколько приемов:
1. Создать класс LocalizationService, который будет заведовать ресурсами в зависимости от CurrentCultureInfo.
Т.е. он должен содержать в себе (или вызывать у CurrentLocalization) ту самую функцию GetString.
2. Создать класс LocalizedString, приводящийся к строке. В момент приведения она вызывает LocalizationService.GetString
(...) или Localization.Current.GetString(...). В конструктор этой строке передавать алиас. Все такие строки
включить как readonly в соответствующие классы — генератором или руками.
3. Можно вместо алиаса передавать в LocalizedString еще и имя словаря. Наличие словаря проверять в конструкторе. Там же
проверять наличие в словаре такого алиаса. 10 000 проверок при старте никого не напрягут.
4. Написать к студии Add-in, генерящий код класса, типа SR по словарю и редактирующий этот словарь. Чувак вернул в проект
поправленный словарь -> код SR пересобрался, появились/исчезли LocalizedString -> получили ошибку компиляции.
Здравствуйте, V.Petrovski, Вы писали:
VP>Ты меня измени, но у меня такой чувство что ты болен юношеским максимализмом.. VP>На этом мы и занкончим... VP>Я давно уже не новичок в нете (это так к сведению).
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Здравствуйте, V.Petrovski, Вы писали:
ВВ> ВВ> Что-то я вообще ничего не понимаю. Каким образом ты собираешься считывать данные в константу из ресурсов? И что конкретно ты в ресурсах хранишь — откуда рантайм ошибки? Ресурсы в первую очередь предназначены для хранения локализуемых стрингов. И что это за пи-пи-пи зеленые, которые у тебя в ресурсы лезут? Они что по совместительству и специалисты по языкам?
Здравствуйте, V.Petrovski, Вы писали:
VP>Вот тебе пример
VP>
VP>...
VP>internal string const FooterMask = "FooterMask";
Хм, я не совсем правильно понял, что ты в данном случае имел в виду под констами. Я подумал, что речь идет о считывании содержимого ресурсов в константу :) .Но все же непонятно немного, зачем использовать дополнительную конст в данном случае? Не проще ли сразу писать название поле при GetString? Хотя это детали.
VP>...
VP>public string Footer
VP>{
VP> get
VP> {
VP> return String.Format(resourceManager.GetString(FooterMask), CurrentPage, Count);
VP> }
VP>}
VP>...
VP>
VP>а вот ресурс VP>
VP>FooterMasc = Page {0} of {1}
VP>и что произойдет при обращении и свойству Footer?
И что произойдет? Мне кажется это довольно надуманная проблема. Если ты действительно сталкивался с подобной ситуацией, то тогда извини. Но я не понимаю, каким образом человек будет изменять поля в ресурснике, которые не он сам создал? Ведь ежу понятно, что если поле создано до него, к тому же с символу для стрингформата, значит оно где-то уже используется. И если этот человек все же решает его изменить, то он или занимается намеренным зловредительством или у него не в порядке с головой.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, V.Petrovski, Вы писали:
AVK>Если есть что по делу — говори, а рассказывать всем какой ты умный и какие все вокруг дураки не стоит.
Ты на первый пост посмотри. Меня интересует как это делает не только Microsoft, а например 9rays или любые другие конторы который пишут под .NET.
Здравствуйте, V.Petrovski, Вы писали:
VP>Ты на первый пост посмотри. Меня интересует как это делает не только Microsoft, а например 9rays или любые другие конторы который пишут под .NET.
Я тебе предложил посмотреть как это сделано в янусе. Проблем при использовании пока не замечено.
выкинет исключение. И вообще человек не машина, неужели ты никогда не делал опечаток при написании программы? Но тебя спасал компилятор, а здесь ты об "опечатке" узнаешь только в рантайме.
Показатель. Попробуй попасть хотя бы в первую десятку, а потом уж будешь разговаривать с другими с видом доки. Да, позвольте кстати поинтересоваться завершенными Вами проектами?
VP> ну тогда ...
Здравствуйте, AndrewVK, Вы писали:
AVK>Я тебе предложил посмотреть как это сделано в янусе. Проблем при использовании пока не замечено.
И какую версию? у меня сам видешь какая. В этой что у меня у вас может где и используется ResourceManager, но в настройках приложения у вас зашиты напрымую русские строки для аттрибутов (Decription,DicplayName,Category).
Здравствуйте, AndrewVK, Вы писали:
AVK>Показатель. Попробуй попасть хотя бы в первую десятку, а потом уж будешь разговаривать с другими с видом доки. Да, позвольте кстати поинтересоваться завершенными Вами проектами?
Здравствуйте, V.Petrovski, Вы писали:
AVK>>Я тебе предложил посмотреть как это сделано в янусе. Проблем при использовании пока не замечено.
VP>И какую версию?