首页 > 其他分享 >MasaFramework -- i18n (国际化)

MasaFramework -- i18n (国际化)

时间:2023-01-03 09:22:58浏览次数:68  
标签:语言 name -- 本地化 I18n json i18n MasaFramework string

概念

作为一个普通开发者, 我们负责的项目的使用群体大多数是本国的人民, 但不可避免的也有一些做外贸的业务或者给外企做的项目, 这个时候就要求我们的项目有服务全球客户的能力, 而一个支持国际化能力的框架会让我们项目的体验变得更好.

关于本地化我们听到最多的是I18N、L10N、G11N, 那它们分别代表了什么意思呢?

  • I18N: 是"Internationalization" 的缩写, 由于I到N之间间隔了18个字母, 也被简称为"i18n". 使产品或软件具有不同国际市场的普遍适应性, 从而无需重新设计就可适应多种语言和文化习俗的过程. 真正的国际化要在软件设计和文档开发过程中, 使产品或软件的功能和代码设计能处理多种语言和文化习俗, 具有良好的本地化能力. 它让程序具备了支持多种语言的能力
  • L10N: 是"Localization"的缩写, 由于L到N之间间隔了10个字母, 也被简称为"L10N". 是将产品或软件针对特定国际语言和文化进行加工, 使之符合特定区域市场的过程. 真正的本地化要考虑目标区域市场的语言、文化、习俗、特征和标准. 通常包括改变软件的书写系统(输入法)、键盘使用、字体、日期、时间和货币格式等
  • G11N: 是"Globalization"的缩写, 由于G到N之间间隔了11个字母, 也被简称为"G11n", 是指在全球范围内推出产品的业务方面, 可以简单理解为 "I18N" + "L10N"

本地化的意义

本地化包括:

  • 产品本地化
  • 技术研发本地化
  • 原材料本地化
  • 人才本地化
  • 企业文化本地化

经过研究表明, 本地化后的产品的销量会比未经过本地化的更好, 75%的人偏好用母语购买产品, 86%的本地化广告在点击率、转换率上超过未经过本地化的广告, 这些数字都说明了人们对自己母语显示的内容更加感兴趣, 通过本地化可以让你更精准的打动客户, 帮你迅速的进入市场, 但本地化不等于直接翻译, 本地化是基于对当地市场情况和文化精心策划的, 在习惯、习俗、日期和货币格式上是不相同的, 本地化的产品能节约沟通成本, 更容易被理解和接受.

举个通俗的例子: 相比找一个不认识的陌生人买东西, 我们更喜欢去找那个知根知底的本地人买东西, 这无关产品的质量, 只是熟悉的人更容易获得我们的认同感

虽然本地化包括很多模块, 但在此我们只考虑产品的本地化, 下面我们就说一下如何做使得自己的产品可以支持本地化

使用

  1. 新建ASP.NET Core 空项目Assignment.I18nDemo,并安装Masa.Contrib.Globalization.I18n.AspNetCore
dotnet add package Masa.Contrib.Globalization.I18n.AspNetCore --version 0.7.0-preview.16
  1. 注册I18n, 并修改Program.cs
builder.Services.AddI18n();
  1. 使用I18N
app.UseI18n();//启用本地化中间件
  1. 添加多语言资源文件, 文件夹结构如下:
- Resources
  - I18n
    - en-US.json
    - zh-CN.json
    - supportedCultures.json
  • en-US.json
{
    "Home":"Home"
}
  • zh-CN.json
{
    "Home":"首页"
}
  • supportedCultures.json
[
    {
        "Culture":"zh-CN",
        "DisplayName":"中文简体",
        "Icon": "{Replace-Your-Icon}"
    },
    {
        "Culture":"en-US",
        "DisplayName":"English (United States)",
        "Icon": "{Replace-Your-Icon}"
    }
]
  1. 使用I18n
app.Map("/test", (string key) => I18n.T(key));
  1. 测试多语言, 在浏览器访问"https://localhost:7082/get?key=Home"即可得到对应语言下键名为Home的值

是不是感觉用起来十分简单呢, 但这究竟是如何做的呢

进阶

国内的小伙伴根据上面的例子操作下来, 会发现请求响应的内容是中文, 那什么情况下它会变成英文呢?

本地化中间件

由于.NET 提供了本地化的能力, 它提供了本地化的中间件, 通过它使得我们的项目具备解析当前语言的能力

目前它支持了以下三种方式进行语言切换:

  • URL 参数 方式: ?culture=en-US,此方式优先级最高,格式为:culture=区域码
  • Cookies 方式:cookie 格式为 c=%LANGCODE%|uic=%LANGCODE%,其中 c 是 Culture,uic 是 UICulture, 例如:
c=en-UK|uic=en-US
  • 客户端浏览器语言自动匹配:如果前面两种方式都没有设置,支持自动根据客户端浏览器语言进行匹配

语言优先级:

URL 参数 方式 > Cookies方式 > 客户端语言 > 默认语言

默认语言

默认语言有两种配置方式, 它们分别是:

  • 约定配置
    • supportedCultures.json文件中的第一个语言
  • 手动指定默认语言
    • 通过app.UseI18n("{Replace-Your-DefaultCulture}")

它们的优先级是:

手动指定默认语言 > 约定配置

修改默认资源路径

builder.Services.AddI18n(options =>
{
    options.ResourcesDirectory = Path.Combine("Resources", "I18n");//修改默认资源路径
    options.SupportedCultures = new List<CultureModel>() //支持语言
    {
        new("zh-CN"),
        new("en-US")
    };
});

支持资源文件

如果你希望将配置文件嵌入到dll文件中, 不希望被看到修改, 那么你需要将资源json文件的生成操作改为嵌入的资源, 并修改I18N注册代码为:

builder.Services.AddI18nByEmbedded();

嵌套配置

相信了解前端开发的小伙伴也见到过嵌套的资源配置, 那对于Masa提供的多语言方案而言, 我们也支持这种格式的配置, 例如:

{
    "Home":"首页",
    "User":{
        "Name":"名称"
    }
}

我们希望拿到User节点下的Name属性的值, 则可以通过:

var result = I18N.T("User.Name");//其中key的值不区分大小写

当然除此之外, 我们也可以将不同资源的文件分开存放到不同的json文件, 然后通过添加多个资源目录的文件, 最终实现, 但在使用时稍微有区别:

app.Map("/test2", (string key, II18n<CustomResource> i18n) => i18n.T(key));//通过DI获取到自定义资源下Key对应内容

如何对接远程资源配置

多语言的远程资源配置目前仅支持Dcc, 我们可以这样做:

  1. 注册MasaConfiguration并使用Dcc, 修改Program.cs
builder.Services.AddMasaConfiguration(configurationBuilder =>
{
    // configurationBuilder.UseDcc();//正确配置好Dcc配置后开启
});
  1. 配置Dcc配置信息, 修改appsettings.json
{
  "DccOptions": {
    "ManageServiceAddress": "{Replace-Your-DccManagerServiceHost}",
    "RedisOptions": {
      "Servers": [
        {
          "Host": "{Replace-Your-DccUseRedisHost}",
          "Port": 6379
        }
      ],
      "DefaultDatabase": 0,
      "Password": ""
    }
  }
}

对MasaConfiguration有疑问点这里

  1. 注册I18n
builder.Services.AddI18n(
    Path.Combine("Resources", "I18n"),
    "supportedCultures.json",
    options => options.UseDcc());

我们仅需要在/Resources/I18n目录下存放支持语言的配置即可, 具体的语言配置将从Dcc读取 (读取Dcc语言的配置节点: 在Dcc配置下默认AppId下的"Culture.{语言}"), 例如:

如果支持语言为zh-CNen-US, 则默认读取Dcc配置下默认AppId下Culture.zh-CNCulture.en-Us两个配置对象的值, 我们仅需要修改它们的值即可, 并且如果对应的内容发生更改, 项目无需重启即可完成自动更新

源码解读

MasaFramework中, 抽象了多语言的能力, 它提供了

  • string this[string name]: 获取指定name的值 (如果name不存在, 则返回name的值)
  • string? this[string name, bool returnKey]: 获取指定name的值 (如果returnKey为false, 且name不存在, 则返回null)
  • string this[string name, params object[] arguments]: 获取指定name的值, 并根据文化、输入参数格式化响应信息返回 (如果name不存在, 则返回name的值)
  • string? this[string name, bool returnKey, params object[] arguments]: 获取指定name的值, 并根据文化、输入参数格式化响应信息返回 (如果returnKey为false, 且name不存在, 则返回null)
  • string T(string name): 获取指定name的值, 如果name不存在, 则返回name的值
  • string? T(string name, bool returnKey): 获取指定name的值 (如果returnKey为false, 且name不存在, 则返回null)
  • string T(string name, params object[] arguments): 获取指定name的值, 并根据文化、输入参数格式化响应信息返回 (如果name不存在, 则返回name的值)
  • string? T(string name, bool returnKey, params object[] arguments): 获取指定name的值, 并根据文化、输入参数格式化响应信息返回 (如果returnKey为false, 且name不存在, 则返回null)
  • CultureInfo GetCultureInfo(): 获取当前线程的区域性 (被用于需要格式化响应信息的方法)
  • void SetCulture(string cultureName, bool useUserOverride = true): 设置当前线程的区域性
  • void SetCulture(CultureInfo culture): 设置当前线程的区域性
  • CultureInfo GetUiCultureInfo(): 获取资源管理器使用的当前区域性以便在运行时查找区域性特定的资源
  • void SetUiCulture(string cultureName, bool useUserOverride = true): 设置资源管理器使用的当前区域性以便在运行时查找区域性特定的资源
  • void SetUiCulture(CultureInfo culture): 设置资源管理器使用的当前区域性以便在运行时查找区域性特定的资源

我们可以通过DI获取到II18n进而来使用它提供的这些能力, 当然它使用的是资源类型为DefaultResource的资源 (在服务注册时所指向的资源 services.AddI18n()), 除此之外, 我们也可以通过DI获取到II18n<DefaultResource>来使用, 也可以通过I18n(全局静态类)来使用它提供的能力, 但是如果你使用了自定义资源类型, 则只能通过DI获取II18n<{Replace-Your-ResourceType}>来使用.

除此之外, 我们还提供了支持的语言列表的能力, 它被抽象在ILanguageProvider

  • IReadOnlyList GetLanguages(): 获取支持语言集合

我们可以通过DI获取ILanguageProvider来使用, 也可以通过I18n.GetLanguages()来使用

总结

当然, MasaFramework绝不仅仅只是提供了这么简单的多语言的能力, 目前全局异常、Caller也已经支持了多语言, 其他模块也在逐步完善多语言支持, 等之后框架的错误信息也将会支持多语言, 我们的开发体验也将会变得更加友好

参考

本章源码

Assignment18

https://github.com/zhenlei520/MasaFramework.Practice

开源地址

MASA.Framework:https://github.com/masastack/MASA.Framework

MASA.EShop:https://github.com/masalabs/MASA.EShop

MASA.Blazor:https://github.com/BlazorComponent/MASA.Blazor

如果你对我们的 MASA Framework 感兴趣,无论是代码贡献、使用、提 Issue,欢迎联系我们

16373211753064.png

标签:语言,name,--,本地化,I18n,json,i18n,MasaFramework,string
From: https://www.cnblogs.com/zhenlei520/p/16997914.html

相关文章

  • github上传本地代码到仓库教程
    github上传代码教程打开gitbash(右键gitbashhere),输入ssh-keygen-trsa-C"[email protected]"在后面输入给出的地址(/c/Users/Bill/.ssh/id_rsa),passphrase瞎写的......
  • 算法之摩尔投票法
    今天接触了一个很有意思的算法,用于求众数。用力扣的题做起来比较有感觉,https://leetcode.cn/problems/majority-element/。当一群人投票表决某一个事时,想找出占人数一半......
  • 【链表】LeetCode 876.链表的中间结点
    题目链接876.链表的中间结点思路定义两个指针fast和slow,快的指针一次走两步,慢的指针一次走一步,这样当快的指针走到底的时候,慢指针正好在中间。以下两幅图说明了偶数结......
  • React中组件之间是如何通信的 react的组件通信方式有哪些
    一、是什么通信指的是发送者通过某种媒体以某种格式来传递信息到收信者以达到某个目的,广义上,任何信息的传递都是通信二、如何通信?组件传递的方式有很多种,根据传送......
  • 学习2023.1.3
    data:znode相关的业务数据均存储在这里,但是,父节点不可存储数据;children:存储当前节点的子节点引用信息,因为内存限制,所以 znode的子节点数不是无限的;stat:包含zno......
  • 狄利克雷卷积和莫比乌斯反演初探(施工中)
    0.前置知识瞅这1.狄利克雷卷积定义定义域为\(\mathbb{N_+}\)的函数称为数论函数。对于两个数论函数\(f,g\),其狄利克雷卷积为\(h(n)=\sum\limits_{d\midn}f(d)......
  • 冒泡排序
    冒泡排序冒泡排序无疑是最为出名的排序算法之一,总共有八大排序!八大排序:冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、堆排序、基数排序。冒泡的代码还......
  • virtualbox 上安装 esxi 6.7 不认识网卡( no network adapters)
    esxi6.7安装会有各种要求,CPU大于等于2颗,内存大于等于4G等等,还有就是网卡可能提示找不到,默认网卡类型不认识,选这个就行了: ......
  • 如何在多个应用程序中共享日志配置
    有的时候你有多个应用程序,它们需要使用相同的日志配置。在这种情况下,你可以将日志配置放在一个共享的位置,然后通过项目文件快速引用。方便快捷,不用重复配置。Directory.Bu......
  • 学习笔记之在免费服务器上运行springboot程序
    因为项目需求,了解到了这个sanfengyun网站,可以申请免费虚拟主机和免费云服务器。申请到免费云服务器后,可以看到自己的控制台主页里有所有的信息。(其中网址如下图所示)idea......