ABP: восстановление источников локализации из настраиваемого поставщика

Я использую ABP v4.9.0 (.NET CORE 2.2) с клиентом angular

Я создал несколько специализированных провайдеров локализации. Эти поставщики получают словари переводов из внешнего API. Я добавляю источники локализации при запуске с этими поставщиками.

            var customProvider = new CustomLocalizationProvider(...);


            var localizationSource = new DictionaryBasedLocalizationSource("SOURCENAME", customProvider );
            config.Localization.Sources.Add(localizationSource );

При запуске вызывается поставщик InitializeDictionaries () и создаются словари локализации. Пока все хорошо, работает как задумано.

Теперь я хочу вручную перезагрузить эти переводы по запросу, но у меня это не работает.

Вот что я пробовал.

Здесь я запускаю повторную синхронизацию языковых ресурсов:

        foreach (var localizationSource in _localizationConfiguration.Sources)
        {
            try
            {
                localizationSource.Initialize(_localizationConfiguration, _iocResolver);
            }
            catch (Exception e)
            {
                Logger.Warn($"Could not get Localization Data for source '{localizationSource.Name}'", e);
            }
        }

В кастомном провайдере я сначала очищаю словари

    public class CustomLocalizationProvider : LocalizationDictionaryProviderBase
    {

    protected int IterationNo = 0;

    protected override void InitializeDictionaries()
    {
        Dictionaries.Clear();

        IterationNo += 1;

        var deDict = new LocalizationDictionary(new CultureInfo("de-DE"));
        deDict["HelloWorld"] = $"Hallo Welt Nummer {IterationNo}";
        Dictionaries.Add("de-DE", deDict);

        var enDict = new LocalizationDictionary(new CultureInfo("en"));
        enDict["HelloWorld"] = $"Hello World number {IterationNo}";
        Dictionaries.Add("en", enDict);
    }

    }

Провайдер снова выполняется, как и ожидалось.

Но когда я в конечном итоге использую клиентскую локализацию (angular), я все равно получаю оригинальные переводы.

Что мне не хватает?

Спасибо за помощь.


person Puur    schedule 23.01.2020    source источник
comment
Вам также нужно обновить на стороне клиента (Angular).   -  person aaron    schedule 27.01.2020
comment
Я, конечно, обновил клиента. Старые переводы кажутся кешированными на стороне сервера, а не только на стороне клиента.   -  person Puur    schedule 27.01.2020
comment
Исправление: использую ABP 4.9.0 (CORE 2.2)   -  person Puur    schedule 27.01.2020
comment
Что такое language.LanguageCode? Вы правы, что источник и поставщик кэшируются, но DictionaryBasedLocalizationSource.GetAllStrings, похоже, использует последнюю версию Dictionaries: DictionaryBasedLocalizationSource.cs # L141   -  person aaron    schedule 27.01.2020
comment
language.Language - это отрывок из гораздо более длинного кода, использующего данные из некоторой внешней службы.   -  person Puur    schedule 29.01.2020
comment
Чтобы помочь вам понять и убедиться, что проблема не во внешней службе, я заменил приведенный выше код фиктивной реализацией InitializeDictionaries (); - Результатом локализации всегда будет Hallo Welt Nummer 1 в клиенте.   -  person Puur    schedule 29.01.2020
comment
@aaron: DictionaryBasedLocalizationSource.GetAllStrings также возвращает исходные, кэшированные исходники.   -  person Puur    schedule 30.01.2020
comment
Это не так: acjh / aspnetboilerplate @ 0f6795e. Можете ли вы написать модульный тест, который воспроизводит это?   -  person aaron    schedule 30.01.2020
comment
Спасибо за старания @aaron. Нет, я не знаю, как воспроизвести этот точный сценарий. 1.) Он не «последовательный», как в вашем модульном тесте. - 2.) Мне никогда не удается явно выполнить CustomLocalizationProvider.InitializeDictionaries (); это делается внутри abp и источником локализации (?) - 3.) Я не контролирую, что явно указывает на экземпляр LocalizationSource, который я использую в каком-то другом сервисе приложений. Он вводится. Введенный экземпляр содержит старые значения. 4.) Более того, и самое главное: я не контролирую, как источник локализации предоставляется клиенту (и я не понимаю этого, TBH ...)   -  person Puur    schedule 31.01.2020
comment
Также пробовал с localizationSource.Initialize, как вы показываете в вопросе: acjplateh / aspnet5cailer7   -  person aaron    schedule 31.01.2020
comment
Круто, спасибо. По-прежнему не решает мою проблему. Клиент использует оригинальные переводы.   -  person Puur    schedule 03.02.2020
comment
Можете ли вы поделиться проектом, который воспроизводит это?   -  person aaron    schedule 03.02.2020
comment
Я взял последний шаблон abp и вставил демо-код. Я отметил свои изменения ключевым словом @Puur - testcase: нажмите «Обновить» и перезагрузите страницу. ожидаемый результат: 'Hello World 2' mediafire.com/file/6sw61614cllsh5c/LocalizationDemo2. zip / файл   -  person Puur    schedule 03.02.2020
comment
Пожалуйста, загрузите его на GitHub с вашими изменениями в отдельном коммите. Еще лучше, если вы можете создать вилку aspnetboilerplate / module-zero-core-template.   -  person aaron    schedule 03.02.2020
comment
Вот и все: github.com/osoDev/module-zero- core-template / commits / v4.x   -  person Puur    schedule 03.02.2020
comment
Я тоже пытаюсь добиться этого с помощью настраиваемых загружаемых словарей, которыми я могу управлять во время выполнения. Я считаю, что вы лаете не на то дерево ... Но в то же время я не могу увидеть нужное дерево в другом месте приложения. : S Я считаю, что вам нужно как-то добраться до Configuration.Localization.Sources; затем удалите его и повторно добавьте новый экземпляр (чтобы убедиться, что он правильно инициализируется; или, по крайней мере, в моем случае это то, что мне нужно). В вашем репо код находится в aspnet-core/src/AbpCompanyName.AbpProjectName.Core/Localization/AbpProjectNameLocalizationConfigurer.cs#L12-L19. (...)   -  person Avenger    schedule 10.02.2020
comment
Этот код вызывается из aspnet-core/src/AbpCompanyName.AbpProjectName.Core/AbpProjectNameCoreModule.cs#L27 (модуля PreInitialize()). Я подозреваю, что если вы каким-то образом повторно добавите этот источник локализации, он должен обновиться для оставшихся запросов. Но я просто не могу попасть в это Configuration.Localization.Sources извне модуля. : /   -  person Avenger    schedule 10.02.2020
comment
4 часа борьбы с этим, и я смог заставить его работать по подходу, очень похожему на ваш. похоже, единственная разница в том, что я тоже присваиваю DefaultDictionary = enDict;. Может быть, вы запрашиваете словарь по умолчанию, но не заменили его должным образом?   -  person Avenger    schedule 10.02.2020


Ответы (1)


Тем временем мне пришлось пойти на другой подход.

Теперь я использую XmlEmbeddedFileLocalizationDictionaryProvider, завернутый в MultiTenantLocalizationDictionaryProvider. Таким образом, я использую db-локализации с xml-источниками как запасной вариант.

Затем я вручную загружаю ресурсы из своего API в какой-нибудь сервис приложений. Эти локализации затем обновляются в базе данных с помощью LanguageTextManager.UpdateStringAsync().

person Puur    schedule 11.08.2020