另类方式实现.Net下的多语言

前言

关于.Net下的多语言方案已经有很多成熟的方案,例如:# Avalonia 国际化之路:Resx 资源文件的深度应用与探索,或者# Avalonia使用XML文件实现国际化,基本都围绕官方的Satellite Assembly方案来实现。实际上,我们可以使用非常原始的方式来实现多语言。

步骤

1. resources资源文件生成

创建如下文本文件(假设为rex.txt)

Greeting=Hello

将ResGen.exe从framework的工具目录(使用everything找下就可以看到)拷贝到当前目录,执行如下命令

PS D:\workSpace\Code\测试\resx> .\ResGen.exe .\rex.txt
Read in 1 resources from ".\rex.txt"
Writing resource file...  Done.

就可以得到我们第一步的rex.resources

说明:
ResGen.exe工具同样支持resx文件,具体使用与文件格式参考https://learn.microsoft.com/en-us/dotnet/framework/tools/resgen-exe-resource-file-generator 官方文档,事实上,这也是我们使用的IDE编辑时msbuild背后调用的工具。

2. Dll文件生成

有了resources资源文件,我们就可以通过链接器(al.exe,同样在framework的工具目录中)将resources资源文件链接成动态链接库。

PS D:\workSpace\Code\测试\resx> .\al.exe -target:lib -embed:.\rex.resources -out:Res.dll
Microsoft(R) Assembly Linker 版本 14.7.2053.0
Copyright (C) Microsoft Corporation. All rights reserved.

说明:

  1. -target:lib代表产物为类库
  2. -embed:.\rex.resources代表嵌入刚刚第一步的生成资源文件
  3. -out:Res.dll 代表生成物名称
  4. 使用ilspy打开就可以看到嵌入的资源文件。
  5. 注意我们这里并没有指定-culture:zh-Hans参数,而官方文档说这个参数必须传(https://learn.microsoft.com/en-us/dotnet/core/extensions/create-satellite-assemblies) 是因为我们完全没使用.net的语言资源机制,也完全不用遵从其hub-and-spoke模型(指的是轮子的中心和车轮的辐条的关系模型,也就是主dll和卫星资源dll的位置关系模型)
  6. 这里要对.Net下dll的结构有一定认识,大家可以参考前面链接中的图片。
  7. 也可以使用-template:Example.dll来指定生成dll的元数据模版,不然生成的dll在ilspy中元数据表的TypeDef会显示<Module>这样未命名的记录。
  8. 我们这里用的是链接器,其实也能用编译器(.net core下就是这样),参考前面的链接。

3. 使用

创建控制台应用,代码如下:

using System;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Threading;namespace ConsoleApp1
{internal class Program{static void Main(string[] args){// 手动加载刚刚链接器生成的程序集Assembly ass = Assembly.LoadFile(@"D:\workSpace\Code\测试\resx\Res.dll");// 第一个参数"rex"即为我们嵌入的rex.resources的文件名,第二个参数为应用程序集ResourceManager rm = new ResourceManager("rex", ass);var s = rm.GetString("Greeting");Console.WriteLine(s);}}
}

输出为:

HelloD:\workSpace\Code\测试\resx\ConsoleApp1\bin\Debug\ConsoleApp1.exe (进程 5184)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .

就能拿到我们定义的语言资源啦。

说明:

  1. 由于我们这里是纯手工加载,Thread.CurrentThread.CurrentCulture = new CultureInfo("en-us");这样是完全没影响的,同样, 链接器的cultrue参数也不影响,大家可以自行测试。

How to:

看完这个和文章中的参考资料,应该对大家理解.Net的多语言有很大帮助。接下来就是我的方案(也许是胡说)
如果想统一在一个文件中管理整个sln的语言资源(举例一下特殊需求),可以通过msbuild自定义Task的方式(大家可以类比下编辑的Grpc的proto文件自动生成代码的过程,实际上谷歌也是这么干的),(或者结合下T4模版?)直接生成所有语言的ResourceManager字典。封装方法返回对应语言的资源,有特殊需求的可以自行尝试,如果不行就当我是胡说。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/888618.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

抽象类和接口的对比、及各自的使用场景--java进阶day02

1.区别2.各自的使用场景1.抽象类的使用场景 如图,有三个类,其中存在共性,我们就会写一个父类并抽取出共性的东西,但有的方法难免会描述不清,所以我们就将其写为了抽象方法,抽象方法又得存在于抽象类中,所以抽象类主要是对事物做抽象,有些事物说不清2.接口的使用场景假如…

JUC并发—11.线程池源码分析

大纲 1.线程池的优势和JUC提供的线程池 2.ThreadPoolExecutor和Excutors创建的线程池 3.如何设计一个线程池 4.ThreadPoolExecutor线程池的执行流程 5.ThreadPoolExecutor的源码分析 6.如何合理设置线程池参数 + 定制线程池1.线程池的优势和JUC提供的线程池 (1)为什么使用线程池…

Redis中的缓存穿透,缓存击穿和缓存雪崩

概述 缓存击穿、缓存穿透、缓存雪崩这三个问题是Reids在实际项目中会经常遇到问题,同时,这三个问题也是面试的热点问题,下面,就本篇文章搞懂缓存穿透、缓存击穿、缓存雪崩三大问题的原因及解决方法。 Redis在项目中作为缓存中间件是如何工作的?如图所示客户端发起一个查询…

接口中的成员特点、类和接口之间的各种关系--java进阶day02

1.接口的成员特点1.接口没有构造方法接口没有构造方法,但是实现类中有构造方法,super()又该访问谁呢? 类实现接口只是认干爹,类本身还是会有亲爹Object,super()会访问Object类2.接口中成员变量只能定义常量 接口会自动将public static final加到成员变量中系统识别到有…

跨平台桌面应用开发:解锁 Electron 与 shadcn/ui 的潜力

本文部分内容使用豆包AI进行撰写和润色在当今数字化转型加速推进的时代,桌面应用程序作为各行各业的关键支撑,持续发挥着不可替代的作用。从医疗领域专业精准的影像诊断软件,助力医生快速洞察病情、制定治疗方案;到建筑设计行业复杂且功能强大的建模工具,将设计师脑海中的…

最新扣子(Coze)实战案例:提效10倍的室内装修设计AI工作流打造流程,让AI帮你做室内风格设计,打造COZE装修应用

最近星球群里有做装修设计行业的同学,想用扣子开发一款室内装修设计的应用,希望使用扣子工作流搭建,并建立扣子应用发到小程序。咨询斜杠君能否分享一下装修行业的扣子应用搭建方法。 ️‍这位同学的需求是: 让用户上传一张尚未装修的室内毛坯图片,选择装修风格后,立即为…

通过LM Studio部署DeepSeek

下载LM Studio 下载地址:https://lmstudio.ai/download 配置软件 汉化点击右下角齿轮设置为中文并使用代理调整模型路径点击文件夹图标 设置模型路径到空间大的磁盘查找并下载模型点击"放大镜"图标,跳出模型查找界面选择合适模型即可下载非限制模型搜索区输入"…

接口介绍以及定义和使用--java进阶day02

1.接口介绍 日常生活中有很多接口,比如手机数据线的接口和手机充电器的接口我们转换视角,站在设计者的角度思考接口,接口体现出规则,手机的接口大小和数据线的接口大小必须一致,各种接口的大小都要一致,都具有规则 所以,接口的本质就是设定规则代码当中又该如何设定规则…

软件开发与创新作业1-逆向-学生选课系统

来源:https://github.com/CurtainXT/Student_Management_System 运行环境:Visual Studio 2022 运行结果:主要代码:点击查看代码 #include"StuManage.h"/*-------------------------------学生工具组--------------------------------*/ // 查看备选课程信息 void…

JEXL 入门实战

JEXL 是一个在 Java 中实现动态表达式和脚本功能的库,本文主要介绍其基本概率和使用。 1、背景 在软件开发中,动态执行表达式是一项非常重要的能力。特别是在动态规则处理、配置文件解析以及灵活的业务逻辑实现等场景下,使用一种能够在运行时解析和执行表达式的工具显得尤为…

Octopus游戏服务器框架

Octopus一个跨平台的lua游戏服务器开发框架,该框架代码采用C++编写,开发者只需要调用SDK提供的接口函数和绑定对应的回调函数即可。框架在逻辑层表现为单线程的开发模式,使开发者更加易使用,易调试,易维护,易扩展,同时确保有快速的响应能力。 框架使用面向对象的开发模式…

【蓝牙小程序】实现简易table表格

Demo效果图 正文 由于需要开发小程序,前端又是自己弄,类似table的标签也没有,后来看到小程序文档中推荐使用flex布局,就把css中的flex布局学了一遍,效果还行,大家将就看一下table.wxml <view class="table"><view class="tr bg-w"><…