DuMes.Component.I18N 6.0.1

dotnet add package DuMes.Component.I18N --version 6.0.1
                    
NuGet\Install-Package DuMes.Component.I18N -Version 6.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="DuMes.Component.I18N" Version="6.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DuMes.Component.I18N" Version="6.0.1" />
                    
Directory.Packages.props
<PackageReference Include="DuMes.Component.I18N" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add DuMes.Component.I18N --version 6.0.1
                    
#r "nuget: DuMes.Component.I18N, 6.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package DuMes.Component.I18N@6.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=DuMes.Component.I18N&version=6.0.1
                    
Install as a Cake Addin
#tool nuget:?package=DuMes.Component.I18N&version=6.0.1
                    
Install as a Cake Tool

DuMes.Component.I18N

多脉本地化组件:按固定目录约定加载 JSON 文案,通过泛型资源类型 + 点号键解析多语言文本,并支持浏览器 Accept-Language

项目结构

DuMes.Component.I18N/
├── Abstractions/                    # II18NService
├── Context/                        # 当前请求语言(AsyncLocal)
├── Extensions/                     # AddI18N / UseI18N / GetLanguage<T>
│                                   # I18NLibrarySegmentValidator(末段唯一性)
├── Middleware/                     # Accept-Language 解析
├── Options/                        # I18NOptions、I18NLanguageSettings
└── Services/                       # I18NService、I18NAccessor(静态入口)

功能概览

能力 说明
资源约定 Resources/I18N/{语言}/{类库末段}/{类型名}.json
泛型定位 "xxx".GetLanguage<T>(),由 T 所在程序集末段 + 类型名定位文件
嵌套键 JSON 对象扁平化为 xxx.xxx(如 HttpStatus.BadRequest
语言解析 优先 Accept-Language,否则使用配置默认语言
Swagger DuMes.Component.FastEndpointsAddModules 注入下拉;选项来自 I18N:SupportedLanguages(须先 AddI18N
大小写 语言目录、类库目录、JSON 文件名均忽略大小写(zh-cn / zh-CN 均可)
缺失回退 找不到键时回退为键本身,不抛错;写入 logs/language_warning.log
启动清理 AddI18N 时清空上次残留的 language_warning 日志
末段冲突 多个程序集末段相同且都提供对应 JSON 标记类型时直接抛错,禁止启动(不写日志)
配置校验 DefaultLanguage / SupportedLanguages 必须在磁盘有对应语言目录,否则禁止启动

资源目录约定

输出目录(AppContext.BaseDirectory)下:

Resources/I18N/
├── zh-CN/
│   ├── Identity/                    ← DuMes.Module.Identity 的末段
│   │   └── SystemI18N.json          ← GetLanguage<SystemI18N>()
│   └── FastEndpoints/               ← DuMes.Component.FastEndpoints 的末段
│       └── FastEndpointsI18N.json   ← GetLanguage<FastEndpointsI18N>()
└── en/
    ├── Identity/
    │   └── SystemI18N.json
    └── FastEndpoints/
        └── FastEndpointsI18N.json

路径公式:

Resources/I18N/{culture}/{程序集名最后一段}/{标记类型名}.json

示例:

标记类型 所在类库 解析路径
SystemI18N DuMes.Module.Identity Resources/I18N/zh-CN/Identity/SystemI18N.json
FastEndpointsI18N DuMes.Component.FastEndpoints Resources/I18N/zh-CN/FastEndpoints/FastEndpointsI18N.json

提供资源的项目需将文件复制到输出目录,例如:

<None Include="Resources\**\*.*">
  <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>

JSON 示例

{
  "Test": {
    "V1": "测试V1"
  },
  "TestV2": "测试V2",
  // 支持注释与尾逗号
  "Count": 3
}

对应键:Test.V1TestV2Count(数字/布尔/null 会转为字符串;数组不参与扁平化)。

接入

1. 引用

Host 或消费方 ProjectReference / NuGet 引用本组件。依赖 DuMes.Component.Serilog(缺失键警告落盘到 logs/language_warning.log)。

建议 Host 同时接入 Serilog 管道(builder.Host.UseComponentSerilog()),否则 WriteWarning 可能无法按预期写文件。

若使用模块宿主 Swagger 语言下拉,还需引用 DuMes.Component.FastEndpoints,并保证 AddI18NAddModules 之前

2. 配置 appsettings.json

I18N 节与 DefaultLanguage 为必填。SupportedLanguages

  • 用于 Swagger 下拉与运行时匹配
  • 未配置或为空时自动回退为仅含 DefaultLanguage
  • 若列表不含默认语言,会自动插入到首位
  • 每个语言必须存在 Resources/I18N/{culture}/ 目录,否则启动失败
{
  "I18N": {
    "DefaultLanguage": "zh-CN",
    "SupportedLanguages": [ "zh-CN", "en" ]
  }
}

3. Program.cs

using DuMes.Component.I18N.Extensions;

builder.Services.AddI18N(builder.Configuration);   // 须在 AddModules 之前
builder.Services.AddModules(...);

var app = builder.Build();

app.UseI18N();   // 须在业务中间件 / Endpoint 之前

4. 定义资源标记类型

namespace DuMes.Module.Identity;

/// <summary>对应 Resources/I18N/{culture}/Identity/SystemI18N.json</summary>
public abstract class SystemI18N;

5. 使用

using DuMes.Component.I18N.Extensions;

var text = "Test.V1".GetLanguage<SystemI18N>();

必须传入泛型;由类型所在类库末段 + 类型名定位 JSON。

  • GetLanguage<T>():依赖静态入口,须已调用 UseI18N
  • 注入 II18NService:仅需 AddI18N 即可

语言匹配规则

  1. 解析请求头 Accept-Language(按 q 值降序;* 忽略)
  2. 与配置的 SupportedLanguages 磁盘上额外的语言目录做忽略大小写匹配
  3. 匹配顺序:
    • 精确匹配zh-CNzh-CN
    • 请求为裸主语言时(如 zh)→ 可匹配同主语言的区域变体(如 zh-CN;多条时取列表第一个)
    • 请求带区域时(如 zh-TW)→ 匹配兄弟方言(zh-CN);仅当存在纯主语言标签 zh 时才回退到 zh
  4. 未匹配则使用 I18N:DefaultLanguage
  5. 取文案时:当前语言 → 默认语言 → 仍无则回退为键本身
    (若当前语言标签因大小写等原因无法映射到磁盘目录,等同直接走默认语言)

非 HTTP 场景(无请求上下文)直接使用默认语言。

注意事项

  1. 路径固定Resources/I18N/{culture}/{类库末段}/{TypeName}.json
  2. 类库末段唯一:若多个程序集末段名相同,且各自都定义了与 Resources/I18N/*/{末段}/*.json 文件名对应的标记类型,则视为冲突;AddI18NUseI18N 均会校验,重复则直接抛错退出,不写日志。不按程序集业务名称前缀过滤。
  3. 类型名 = JSON 文件名GetLanguage<SystemI18N>() 读取 SystemI18N.json
  4. 复制到输出:未设置 CopyToOutputDirectory 时,配置语言目录缺失会导致启动失败;单个 JSON 文件缺失则回退为键并写 language_warning
  5. 先 Add 再 Use:未调用 UseI18NGetLanguage 会抛未初始化异常;注入 II18NService 不受此限。
  6. 中间件顺序UseI18N 须在 Endpoint 之前;AddI18N 须在 AddModules 之前(否则 Swagger 无语言下拉)。
  7. 缺失不抛错:找不到键时返回键本身,详情见 logs/language_warning.log
  8. 键大小写敏感Test.V1test.v1
  9. 数组不支持:JSON 数组不参与扁平化查找;注释、尾逗号、数字/布尔/null 可用。
  10. 资源缓存:成功读到的 JSON 会缓存至进程结束;文件不存在不缓存(开发期补文件后下次请求可加载,无需为 miss 重启)。JSON 内容变更仍需重启进程。
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
6.0.1 91 8/9/2026
6.0.0 92 8/6/2026