本地化和全球化架构常见问题解答: 第 2 部分






3.43/5 (25投票s)
本地化与全球化架构常见问题解答:第二部分。
目录
- 引言
- (A) AL.EXE 和 RESGEN.EXE 是什么?
- (I) 资源管理器类有什么用?
- (A) 部署卫星程序集时需要注意哪些事项?
- (A) 能否解释一下“GetGlobalResourceObject”和“GetLocalResourceObject”函数的原理?
- (A) 能否为卫星程序集签名?
- (I) 能否解释一下 SQL Server 中的排序规则序列?
- (A) 如何为数据库和表定义排序规则序列?
- (A) 能否在 Select 查询中改变排序,使其具有指定的排序规则序列?
- (A) 能否列出全球化和本地化的最佳实践?
- 参考文献
- 其他面试问题 PDF
引言
您可以在 LocalizationGlobalizPart1.aspx 处查看本文的第一部分。
当我们放眼四周,会发现架构主要讨论松耦合、可伸缩性、性能等。许多架构都忽略了软件中一个重要的方面,那就是使应用程序全球化。根据项目的不同,有些应用程序可能不需要多语言的网站,但我相信许多应用程序都会需要。因此,在本文中,我们将通过一系列常见问题解答,为您提供一个快速入门,帮助您构建多语言应用程序。
最近我一直在编写和录制关于设计模式、UML 和各种架构方面的视频,您可以在 http://www.questpond.com 找到设计模式和 UML 视频。您可以在以下链接中阅读我之前关于设计模式和 UML 的文章:
- 第一部分 – 设计模式:工厂模式、抽象工厂模式、建造者模式、原型模式、浅复制和深复制,以及单例模式和命令模式: SoftArchInter1.aspx
- 第二部分 – 设计模式:解释器模式、迭代器模式、中介者模式、备忘录模式和观察者模式: SoftArch2.aspx
- 第三部分 – 设计模式:状态模式、策略模式、访问者模式、适配器模式和享元模式: SoftArch3.aspx
- 第四部分 设计模式:桥接模式、组合模式、装饰器模式、外观模式、组合模式、代理模式和模板模式: SoftArch4.aspx
- 使用 IOCDI.aspx 实现松耦合架构
- 您可以从 http://www.questpond.com/softArchi.zip.zip 下载我的架构面试题集。
(A) AL.EXE 和 RESGEN.EXE 是什么?
在上一个部分,您已经了解了如何使用资源文件根据本地化语言存储数据。但是,在实际部署时,您可能不希望安装“resx”或“txt”文件。安装容易被修改的数据绝对不是一个好的部署实践。简而言之,我们应该以二进制格式安装这些数据,以免最终用户修改。这就是 Microsoft 引入卫星程序集的原因。卫星程序集是不包含源代码的程序集。它们只包含资源文件。您可以使用 *rsgen.exe* 和 *al.exe* 创建卫星程序集。它们是二进制 DLL 格式,便于在部署期间分发。因此,最终在部署时,您不需要分发 *resx* 文件,只需分发编译后的卫星 DLL。
上面的图表为您提供了生成卫星程序集的完整画面。从上图可以看出,我们需要两个可执行文件:*resgen.exe* 和 *al.exe*。一旦您创建了 resx 文件或文本文件,就应该先将其转换为“*.resource*”文件。这是通过使用 *resgen.exe* 完成的。下面是 *resgen.exe* 的命令片段,其中 *LoginScreen.aspx.el.resx* 是 resx 文件,输出是 *Greek. Resources* 文件。如果您不提供输出文件名,它将生成“*LoginScreen.resources*”。
Resgen LoginScreen.aspx.el.resx Greek.Resources
您也可以使用 *resgen.exe* 从文本文件生成 resx 文件,下面是代码片段:
Resgen MyLanguage.txt MyLanguage.resx
上面的命令片段将使用 *MyLanguag.txt* 文件生成 *MyLanguage.resx*。您可以使用资源文件而不是 resx 文件创建 DLL,因此您应该进行此转换。现在,一旦生成了资源文件,就可以创建编译后的程序集,以便在部署时分发。这是通过使用 Microsoft 提供的程序集链接器工具 *al.exe* 来实现的。下面是相同的命令代码片段:
al.exe /out: el.dll /c: de /embed: greek.resources
在 /out 开关中,您需要提供输出 DLL 名称。在 /c 中,您需要指定资源文件的区域设置。使用 /embed,您需要指定资源文件中存在的所有资源。如前所述,除了字符串,您还可以放入 GIF、BMP 等图像文件。因此,您可以在 /embed 开关中指定这些物理资源。您可以使用“,”作为分隔符来指定多个资源文件。
(I) 资源管理器类有什么用?
资源管理器类帮助我们读取资源文件并通过键获取值。首先,您需要创建一个资源管理器对象。您需要在构造函数中指定资源名称和程序集。
privateResourceManagerobjResourceManager =
new ResourceManager("Globalization.resource",
System.Reflection.Assembly.GetExecutingAssembly());
一旦资源管理器填充了详细信息,您就可以使用 `GetString` 函数通过键获取值。例如,在下面的代码片段中,我们使用 `cmdAddNew` 键来获取按钮 `cmdAddNew` 的值。
cmdAddNew.Text = objResourceManager.GetString("cmdAddNew");
(A) 部署卫星程序集时需要注意哪些事项?
部署程序集时,文件夹结构必须非常规范。下表显示了文件夹结构应如何组织。主文件夹是主应用程序文件夹。所有卫星程序集都应部署在主应用程序文件夹内各自的文件夹中。各自的文件夹由区域代码表示。
从上图可以看出,印地语卫星程序集部署在 *hi* 文件夹中,希腊语卫星程序集部署在 *el* 文件夹中,依此类推。如果程序找不到某个区域设置的资源文件,它将使用不变区域设置的卫星程序集。上述文件夹结构是在部署卫星程序集时的严格要求。任何文件夹结构的不匹配都可能导致不当结果。
(A) 是否可以使用强类型资源类而不是资源管理器?
在上一个问题中,我们看到了如何使用资源管理器类从资源文件中读取字符串。然而,VS.NET 2005 在资源支持方面有了显著的改进。您不再需要使用资源管理器类加载。但是,Microsoft 仍然保留它以实现向后兼容。您现在可以在 VS.NET 智能提示中获得强类型类,如下图所示。
所有都属于 `Resources` 命名空间。让我们做一个小示例,看看强类型类如何在 VS.NET 2005 中工作,以及它们在项目中实现全球化时带来的简洁性。下面是项目的屏幕截图。这是一个简单的登录屏幕,带有用户 ID 和密码文本框。用户可以选择语言。目前只提供两种语言:英语和希腊语。根据选择的语言,将显示用户 ID 和密码标签的值。
注意:在全局化项目中,您可以在“*LoginScreenUsingStrongType.aspx*”中找到项目示例。
下面是描述代码中各种重要部分的 Snippet。首先是资源文件。我们生成了两个资源文件,一个是希腊语,后缀为 *el*,还有一个通用资源文件,将在区域代码不匹配时使用。
代码中有三个重要步骤:
- 第一步是使用新的 `CultureInfo` 对象设置当前线程的区域设置信息。结构包含语言代码,即下拉列表中当前选择的语言。
Thread.CurrentThread.CurrentCulture = new CultureInfo (structure);
- 我们将相同的区域设置赋给 `Resource` 类。
Resources.Resource.Culture = Thread.CurrentThread.CurrentCulture;
- 现在我们已经准备好使用该值了。
lblUserId.Text = Resources.Resource.lblUserIdResource1.ToString (); blPassword.Text = Resources.Resource.lblPasswordResource1.ToString ();
注意:您可以在全局化文件夹的“*LoginScreenUsingStrongType.aspx*”中找到相同的内容。尝试添加一种新语言,大多数基本概念都会变得清晰。
(A) 能否解释一下“GetGlobalResourceObject”和“GetLocalResourceObject”函数的原理?
这两个函数属于 `HttpContext` 对象。使用它们,您可以获取资源对象的对象引用。例如,您可以从下面的代码片段中看到,我们有指向全局资源对象的引用,并且我们正在尝试获取“`lblUserIdresource1`”键的值。
lblUserId.Text=HttpContext.GetGlobalResourceObject("Resource", "lblUserIdResource1").To String();
注意:在同一个全局化文件夹中,有“*LoginScreenUsingGetGlobal.aspx*”演示了“`GetGlobalResource`”的工作原理。
一个简短的说明:因为“`GetGlobalResourceObject`”和“`GetLocalResourceObject`”在当前的 `HttpContext` 中运行。它使用从浏览器端设置的区域设置。
(A) 能否为卫星程序集签名?
是的,您可以使用 /keyfile 开关为卫星程序集签名,该开关接受“*.snk*”文件作为输入参数。
al /res:MyLanguage.resources /c:de /keyfile:MyLang.snk out:MyLanguages.resources.dll
(I) 能否解释一下 SQL Server 中的排序规则序列?
首先,让我们定义排序规则。排序规则序列是一组规则,用于确定数据的排序和比较方式。排序规则可以通过选项来定义,包括区分大小写、重音符号、假名字符类型和字符宽度。
区分大小写
如果 A 和 a、B 和 b 等被视为相同,则为不区分大小写。计算机将 A 和 a 视为不同,因为它使用 ASCII 码来区分输入。A 的 ASCII 值为 65,而 a 的 ASCII 值为 97。B 的 ASCII 值为 66,而 b 的 ASCII 值为 98。
区分重音符号
如果 a 和 á、o 和 ó 被视为相同,则为不区分重音符号。计算机将 a 和 á 视为不同,因为它使用 ASCII 码来区分输入。a 的 ASCII 值为 97,á 的 ASCII 值为 225。o 的 ASCII 值为 111,ó 的 ASCII 值为 243。
假名区分
当日语假名字符平假名和片假名被视为不同时,称为假名敏感。
宽度敏感
当单字节字符(半角)和该字符以双字节字符(全角)表示时被视为不同时,则为宽度敏感。
(A) 如何为数据库和表定义排序规则序列?
您可以创建一个具有特定语言排序规则序列的数据库。例如,在下面的 `Create` 语句中,`tblCustomer` 是通过拉丁语排序规则序列创建的。
Create database tblCustomer collate Latin1_General_BIN
您也可以创建具有特定排序规则序列的表。下面是相应的 `Create Table` 语法。
Create table tblCustomer
(
[CustomerCode] char(10) COLLATE Albanian_CI_AI_KS_WS NULL,
[EntryDate] [char] (8) COLLATE Korean_Wansung_Unicode_CS_AS_KS NOT NULL ,
[CustAbbrev] [char] (2) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
)
(A) 能否在 Select 查询中改变排序,使其具有指定的排序规则序列?
是的,我们可以在 `Order By` 子句中指定排序规则序列。这将根据 `Order By` 子句中定义的排序规则来更改排序。
ORDER BY
{
order_by_expression
[ COLLATE collation_name ]
[ ASC | DESC ]
} [ ,...n ] ]
(A) 能否列出全球化和本地化的最佳实践?
以下是在开发支持国际语言的软件时的最佳实践:
- 不要硬编码字符串或用户界面资源。
- 确保您的应用程序依赖于 Unicode。
- 当您从各种编码读取或写入数据时,请确保使用 `System.Text` 命名空间。许多程序员会假定 ASCII 数据。
- 测试时,请使用实际的国际数据和环境进行测试。
- 当您操作数据(例如数字、日期或货币)时,请确保您正在使用 `System.Globalization` 命名空间中定义的、感知区域设置的类。下表详细说明了实现该功能所需的函数和类。图 14.20:使用的功能和类
- 如果安全决策基于字符串比较或大小写更改操作的结果,请通过显式指定 `CultureInfo.InvariantCulture` 属性来执行不区分区域设置的操作。此实践可确保结果不受 `CultureInfo.CurrentCulture` 值的影响。
- 将所有可本地化资源移到单独的 DLL 中。
- 避免在应用程序中使用包含文本的图像和图标。它们本地化成本很高。
- 为用户界面的字符串长度预留充足的空间。在某些语言中,短语可能需要增加 50-75% 的空间。
- 使用 `System.Resources.ResourceManager` 类根据区域设置检索资源。
- 在应用程序中显式设置 `CurrentUICulture` 和 `CurrentCulture` 属性。不要依赖默认值。
- 请注意,您可以在 ASP.NET 中指定以下三种类型的编码:
- 请求编码指定从客户端浏览器接收到的编码。
- 响应编码指定发送到客户端浏览器的编码。在大多数情况下,这应与请求编码相同。
- 文件编码指定 *.aspx*、*.asmx* 和 *.asax* 文件解析的默认编码。
(A) 为什么将区域设置设置到当前线程?
首先,我来解释一下这个问题。如果您查看设置区域设置信息的代码 Snippet
Thread.CurrentThread.CurrentCulture = new CultureInfo(strCulture);
它使用当前线程来设置。这意味着什么?让我们深入了解一下 IIS 如何处理请求来理解这个概念。当用户请求 IIS 的资源(如 ASPX 页面或其他资源)时,IIS 会在其自己的线程中处理该请求。这意味着,如果 100 个用户向 IIS 发送了资源请求,IIS 将在自己的线程中处理每个请求。简而言之,IIS 将生成 100 个线程来处理这 100 个请求。在不同的线程中拥有不同的区域设置是完全有可能的。因此,当我们设置区域设置时,我们不能将其设置为整个应用程序,因为它会影响所有请求。所以,当我们设置区域设置时,我们将其设置为特定线程,而不是整个应用程序。
如需进一步阅读,请观看以下面试准备视频和分步视频系列。