zoukankan      html  css  js  c++  java
  • 本地化模块

    ABP的本地化系统与Microsoft.Extensions.Localization无缝集成,并与AspnetCore的本地化文档兼容. 它添加了一些实用功能和增强功能, 使其更易于在实际开发中应用.

    SupportedCultures 的 CultureInfo 对象决定了和文化相关的函数,如日期,时间,数字和货币格式的结果。 SupportedCultures 同时决定了文字如何排序,大小写转换以及字符串比较。参考CultureInfo.CurrentCulture 获取更多关于服务器如何获取文化的信息。SupportedUICultures 决定如何通过 ResourceManager 查找翻译字符串(从 .resx 文件)

    Volo.Abp.Localization是本地化系统的核心包.本地化资源用于将相关的本地化字符串组合在一起,并将它们与应用程序的其他本地化字符串分开.通常一个模块会定义自己的本地化资源. 本地化资源就是一个普通的类.

    注意虚拟文件的命名空间与路径,比如AbpValidation,它的命令空间是Volo.Abp.Localization.Resources.AbpValidation,

    则options.FileSets.AddEmbedded<AbpLocalizationModule>("Volo.Abp", "Volo/Abp"),而在AddVirtualJson("/Localization/Resources/AbpValidation")

    public class TestResource
    {
    }
    [DependsOn(typeof(AbpLocalizationModule))]
    public class MyModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            Configure<VirtualFileSystemOptions>(options =>
            {
                // "YourRootNameSpace" 是项目的根命名空间名字. 如果你的项目的根命名空间名字为空,则无需传递此参数.
                options.FileSets.AddEmbedded<MyModule>("YourRootNameSpace");
            });
    
            Configure<AbpLocalizationOptions>(options =>
            {
                options.Resources
                    .Add<TestResource>("en")
                    .AddVirtualJson("/Localization/Resources/Test");
            });
        }
    }
    • 添加了一个新的本地化资源, 使用"en"(英语)作为默认的本地化.
    • 用JSON文件存储本地化字符串.
    • 使用虚拟文件系统 将JSON文件嵌入到程序集中
    •  
     
    {
      "culture": "en",
      "texts": {
        "HelloWorld": "Hello World!"
      }
    }
     
    • 每个本地化文件都需要定义 culture (文化) 代码 (例如 "en" 或 "en-US"). //zh-Hans
    • texts 部分只包含本地化字符串的键值集合 (键也可能有空格)
     
    本地化资源也可以在客户端(JavaScript)使用. 因此, 为本地化资源设置一个简短的名称可以更方便的本地化文本. 例如 
    [LocalizationResourceName("Test")]
    public class TestResource
    {
    }

    资源可以从其他资源继承,这使得可以在不引用现有资源的情况下重用现有的本地化字符串. 例如:[InheritResource(typeof(AbpValidationResource))]

    也可以通过 AbpLocalizationOptions 配置: 

    services.Configure<AbpLocalizationOptions>(options =>
    {
        options.Resources
            .Add<TestResource>("en") //Define the resource by "en" default culture
            .AddVirtualJson("/Localization/Resources/Test") //Add strings from virtual json files
            .AddBaseTypes(typeof(AbpValidationResource)); //Inherit from an existing resource
    });

    资源可以从多个资源继承.如果新的本地化资源定义了相同的本地化字符串, 那么它会覆盖该字符串 

     

    使用AbpStringLocalizerFactory替换了IStringLocalizerFactory,增加单例ResourceManagerStringLocalizerFactory,

    虚拟文件定义,本地化配置文件

    所以整个过程,通过AbpStringLocalizerFactory创建IStringLocalizer,Create(ResourceType)方法,根据这个ResourceType从AbpLocationOption中LocalizationResourceDictionary获取到LocationResource,IStringLocalizer是包装这个LocationResource,用到是LocationResource.Contributor,即JsonVirtualFileLocationResourceContributor去得到相应的语言的值

     

    应用里要先对AbpLocationOption进行配置,首先是根据resourceType(自定义的类,可使用LocalizationResourceName、InheritResource扩展

    在AbpLocalizationOptions.Resources.Add<ResourceType>(默认语言).AddVirtualJson(这个是sonContributor,虚拟文件路径)),增加到LocalizationResourceDictionary,它是管理LocationResource的列表,三个方法 Add<TResouce>(默认语言),AddVirtualJson(),AddBaseTypes

    LocationResource的属性,

    1、ResourceType,在资源文件里新建的类,可加上Attributor可以LocalizationResourceName(), InheritResource(typeof(另一个资源类))

    2、ResourceName》从LocalizationResourceNameAttribute

    3、DefaultCultureName:上面Option方法new要传进来,后续的作用是?如果当前的线程的CultureInfo找不到这个值,则使用这个

    4、BaseResourceTypes:来自InheritResourceAttribute,用于遍历,如果当前找不到,就遍历找InheritResource的type

    5、Contributor List<ILocalizationResourceContributor>: 获取对应的值实现由它要提供,即LocationResource.Contributor.GetOrNull(),只要遍历到一个就返回,实现使用是JsonVirtualFileLocalizationResourceContributor,它扩展

    AbpLocationOption有一个全局的Contributor,这个增加到上面LocaionResource.Contributor里面去。

    在Volo.Abp.AspNetCore.Mvc.Client添加 一个GlobalContributors是RemoteLocalizationContributor,

      

    从工厂Create出来的IStringLocalizer<ResourceType>是AbpDictionaryBasedStringLocalizer,

    首先是AbpLocalizationOptions.Add方法是增加到Resources,LocationResources列表,返回在这个ResourceType的LocaltionResource,再AddVirtualJson是增加到LocationResources的贡献者(Contributes)里面,AddBaseTypes是增加到BaseResourceType里面。 同在Location的初始化的时候,已经将InheritResource作为baseresourceType的增加进去了

    查找到这个前面Add这个Resource里面对应的LocationResource,找不到就使用原来的ResourceManagerStringLocalizerFactory。

    使用ABP,其中要使用的AbpDictionaryBasedStringLocalizer,也要连带List<IStringLocalizer> baseLocalizers

    索引获取方法

    public virtual LocalizedString this[string name] => GetLocalizedString(name); protected virtual LocalizedString GetLocalizedString(string name) { return GetLocalizedString(name, CultureInfo.CurrentUICulture.Name); /当前线程的CultureInfo }

    IStringLocalizer<ResourceType> 的GetLocalizedString(“字符串”)的方法

    它是使用此ResourceType的LocationResource,先使用contributor(这个是JsonVirtualFileLocalizationResourceContributor,读取虚拟文件值,增加到字典里),再从BaseLocationResourceType添加进去

    这个存储的数据结构是Dictionary<string, ILocalizationDictionary>,其中key的索引是cultureCode,而ILocalizationDictionary是StaticLocalizationDictionary(特定语言)

    再根据当前语言值,获取到StaticLocalizationDictionary,再获取对应值LocalizedString

    dictionary[item.Key] = new LocalizedString(item.Key, item.Value.NormalizeLineEndings());

    若GetAllStrings(语言,是否包含默认语言,是否包含基类)

     在AbpApplicationConfigurationController,控制器,[Route("api/abp/application-configuration")],对所有Location进行配置

    protected virtual async Task<ApplicationLocalizationConfigurationDto> GetLocalizationConfigAsync()
            {
                var localizationConfig = new ApplicationLocalizationConfigurationDto();
                localizationConfig.Languages.AddRange(await _languageProvider.GetLanguagesAsync());
                foreach (var resource in _localizationOptions.Resources.Values) //所有的Resources
                {
                    var dictionary = new Dictionary<string, string>();
                    var localizer = _serviceProvider.GetRequiredService(
                        typeof(IStringLocalizer<>).MakeGenericType(resource.ResourceType)
                    ) as IStringLocalizer;
                    foreach (var localizedString in localizer.GetAllStrings())
                    {
                        dictionary[localizedString.Name] = localizedString.Value;
                    }
                    localizationConfig.Values[resource.ResourceName] = dictionary;
                }
                localizationConfig.CurrentCulture = GetCurrentCultureInfo();
                return localizationConfig;
            }

     模块的定义

    [DependsOn(
            typeof(AbpVirtualFileSystemModule),
            typeof(AbpSettingsModule),
            typeof(AbpLocalizationAbstractionsModule)
            )]
        public class AbpLocalizationModule : AbpModule
        {
            public override void ConfigureServices(ServiceConfigurationContext context)
            {
                AbpStringLocalizerFactory.Replace(context.Services);
    
                Configure<VirtualFileSystemOptions>(options =>
                {
                    options.FileSets.AddEmbedded<AbpLocalizationModule>("Volo.Abp", "Volo/Abp");
                });
    
                Configure<AbpLocalizationOptions>(options =>
                {
                    options
                        .Resources
                        .Add<DefaultResource>("en");
    
                    options
                        .Resources
                        .Add<AbpValidationResource>("en")
                        .AddVirtualJson("/Localization/Resources/AbpValidation");
                });
            }
        }
    

     配置Options有三个集合,本地化资源LocalizationResource,本地化资源贡献者ILocalizationResourceContributor,语言种类LanguageInfo

     public class AbpLocalizationOptions
        {
            public LocalizationResourceDictionary Resources { get; }
    
            public ITypeList<ILocalizationResourceContributor> GlobalContributors { get; }
    
            public List<LanguageInfo> Languages { get; }
    
            public AbpLocalizationOptions()
            {
                Resources = new LocalizationResourceDictionary();
                GlobalContributors = new TypeList<ILocalizationResourceContributor>();
                Languages = new List<LanguageInfo>();
            }
        }
    

    AbpCultureHelper.Use,设置当前的语言,同设置租户功能差不多,可以自定义当前线程的CultureInfo和CurrentUICulture,而不用通过中间件进行设置

    public static IDisposable Use([NotNull] CultureInfo culture, CultureInfo uiCulture = null)
            {
                Check.NotNull(culture, nameof(culture));
    
                var currentCulture = CultureInfo.CurrentCulture;
                var currentUiCulture = CultureInfo.CurrentUICulture;
    
                CultureInfo.CurrentCulture = culture;
                CultureInfo.CurrentUICulture = uiCulture ?? culture;
    
                return new DisposeAction(() =>
                {
                    CultureInfo.CurrentCulture = currentCulture;
                    CultureInfo.CurrentUICulture = currentUiCulture;
                });
            }
    

    2、获取本地化文本,在服务端获取本地化文本的用法是非常标准的(它与AspNetCore提供的获取本地化资源方式无缝集成).

    本地化字符串访问器IStringLocalizer<T>,IStringLocalizer 是一个实现了 IEnumerable 的简单接口并且拥有索引器来来返回本地化的字符串。

    AbpDictionaryBasedStringLocalizer,如_localizer["About Title"] 没有发现 “About Title” 的本地化值,则索引的键值被返回

    3、中间件

    https://github.com/aspnet/AspNetCore/blob/e9179bacd7f997a51f9619511985671e0c131a11/src/Middleware/Localization/src/RequestLocalizationMiddleware.cs

     RequestLocalizationOptions:

    Abp赋值了DefaultRequestCulture,SupportedCultures,SupportedUICultures,并且增加Action<RequestLocalizationOptions> optionsAction 委托

    DefaultRequestCulture是默认的cultureName、uiCultureName  ,ABP定义是从SettingProviders中获取得到,GetLanguages

     List<IRequestCultureProvider> RequestCultureProviders,如果有设置,则根据这个是设置当前Culture。默认顺序QueryStringRequestCultureProvider、CookieRequestCultureProvider、AcceptLanguageHeaderRequestCultureProvider

    await provider.DetermineProviderCultureResult(context)  返回地的 ProviderCultureResult,即是List<StringSegment> cultures UIcultures

    目的首先将Culture和UICulture写入当前线程,将Context.Features.设置请求CultureFeature,设置是否将当前Culture返回给客户端,HeaderName.ContentLanguage

    NET 的每个线程都会拥有 CurrentCulture 和CurrentUICulture 对象

    FixedLocalizableString

    public class FixedLocalizableString : ILocalizableString
        {
            public string Value { get; }
    
            public FixedLocalizableString(string value)
            {
                Value = value;
            }
    
            public LocalizedString Localize(IStringLocalizerFactory stringLocalizerFactory)
            {
                return new LocalizedString(Value, Value);
            }
        }
    

    客户端:ABP提供了JavaScript服务, 可以在客户端使用相同的本地化文本. 

    var testResource = abp.localization.getResource('Test');
    var str = testResource('HelloWorld');
  • 相关阅读:
    《那些年啊,那些事——一个程序员的奋斗史》——60
    《那些年啊,那些事——一个程序员的奋斗史》——61
    《那些年啊,那些事——一个程序员的奋斗史》——60
    《那些年啊,那些事——一个程序员的奋斗史》——61
    《那些年啊,那些事——一个程序员的奋斗史》——62
    《那些年啊,那些事——一个程序员的奋斗史》——62
    一个apk多个ICON执行入口
    获取方法的调用者
    INSTALL_FAILED_INSUFFICIENT_STORAGE
    java语言鼠标移动实现
  • 原文地址:https://www.cnblogs.com/cloudsu/p/11171998.html
Copyright © 2011-2022 走看看