应用开源项目StringResourceTool2 实现.NET多国语言方案

我们在应用.net技术开发应用程序时,经常会涉及到使用字符串资源。比如针对不同的国家的用户提供不同的语言的资源,使我们的应用程序更加友好。您完全可以用.net自带的resx文件解决这个问题,但是,StringResourceTool2可以帮助您更优雅的解决这个问题,而且可以充分利用智能感知技术,大大降低出错的机率.

什么是StringResourceTool2

StringResourceTool2是codeplex.com上的一个项目,致力于解决.net 开发中与语言区域有关的资源问题。它的地址是http://stringresourcetool.codeplex.com.

这个项目引入了字符串文件(string file),字符串文件格式早期由微软的企业库引入,方便您在应用程序中使用资源。

从项目的名字中,我们可以看出,它主要是用来解决与语言有关的字符串资源(string resource)的问题。根据字符串资源文件(string file),产生.resx文件,并且生成访问类以方便使用类来访问资源。

更值得称道的是,它还支持类型化参数(typed parameters), 例如: inserts {0}, {1},这简直能让我们的方案趋于完美。

我们知道,.net 标准的资源文件格式是resx文件。默认的生成生成工具是ResXFileCodeGenerator.
如果您的项目中需要用到与特定语种相关的字符串资源,您不妨试一下这个工具,它可以替代Visual Studio 2005中ResXFileCodeGenerator的工具。 另外,它充分运用.net的智能感知功能,大大降低了您在查找字符串时的出错机率。

但是,也许您已经注意到了,它也有局限性。如果您需要针对不同国家的用户提供不同的图片资源,StringResourceTool2不能解决您的需求,从它的名字中就应该看到,它致力于解决字符串资源。

开发中遇到的困惑

在我们日常的开发中,经常需要用到字符串资源。比如,当系统出错时,我们需要提示用户出错了。如果当前用户是英语语种的国家,我们的程序需要提供英语的提示,如果用户习惯的语种是中文简体,我们则需要提供相应的简体中文的报错提示,这样才可以算得上是用户友好的应用程序。

另外,即使您开发的应用不需要涉及多种语种的用户,您也可以从这个项目中获益。把您的与字符串有关的资源集中放到字符串格式文件中,集中管理,方便维护。比如,以前我经常把字符串直接写到各个类中,或是干脆在向用户弹出提示消息时,写到客户端中。这样,随着项目的进入后期阶段,字符串遍及应用程序的各个角落:在数据访问层中抛出异常时有异常提示的字符串资源,在用户界面层中报出错提示时的字符串资源,甚至于每一个窗体的标题,都会增加您后期维护的成本。 如果您在项目开发中是一直对这个问题比较棘手,从项目的一开始,您就很有必要继续看一下下面的内容,它会使您对这个问题有趋于完美的解决办法。

如何在开发中应用

首先,为您的项目添加一个文本文件,命名为SR.strings
clip_image002
图一 添加一个字符串文件

然后,在打开的文件中,直接写入下面的代码

[strings]

Raw = Raw string

StringArg(string name) = With name argument {0}

您在上面的代码中看到了,StringResourceTool2支持类型化参数(typed parameters)。

这种格式也是我们开发中经常会用到

右键点击这个文件,,设置CustomTool属性为StringResourceTool2 或者 SRT2,然后右键点击Run Custom Tool
clip_image004
图二 运行生成工具
工具会生成resx文件以及访问类SR.

我们可以使用下面的代码来访问我们刚才添加的字符串资源文件

string s1 = SR.Raw;

string s2 = SR. StringArg (“Microsoft”);

这就是您需要学习的全部内容:添加一个文本格式的文件(字符串文件),写入您要在项目中使用的字符串,生成资源文件,然后就可以在您的项目中应用了。

如果您希望了解它是如何工作的,下面的内容会帮助您理解它的原理。

它是如何工作的

让我们来回顾一下,如何在.net中使用resx格式的资源文件。

先给您的项目添加如下的资源文件:

clip_image006
图三 添加资源文件

然后使用如下的代码访问资源

ResourceManager rm = new ResourceManager("SampleApplication.ResourceSample.SR", Assembly.GetExecutingAssembly());

string raw = rm.GetString("Raw");

string stringArg = string.Format("{0} world",rm.GetString("StringArg"));

这就是我们经常使用资源文件的方法

再回到我们的StringResourceTool2项目中来。您看到了,一切都很简单,您要做的事情就是添加文本格式的字符串文件,然后运行工具,生成相应的文件,

我们看到了,在我们添加的字符串格式文件中,有如下的特征
clip_image008
图四 生成的文件结构

每一个字符串文件下面,会自动生成一个SR的类文件,和一个resx的资源文件.

SR.srt.resx文件的内容如下
clip_image010
图五 自动生成的资源文件
与我们刚才添加的内容一样。

SR.cs文件看起来如下

public partial class SR

{

public static string Raw

{

get

{

return Keys_SR.GetString(Keys_SR.Raw);

}

}

public static string StringArg(string name)

{

return Keys_SR.GetString(Keys_SR.StringArg, new object[] {

name});

}

internal class Keys_SR

{

public static System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager("SampleApplication.MultiStrings.SR.srt", typeof(SampleApplication.MultiStrings.SR).Assembly);

public const string Raw = "Raw";

public const string StringArg = "StringArg";

public static string GetString(string key, object[] args)

{

string msg = resourceManager.GetString(key, Resources.CultureInfo);

msg = string.Format(msg, args);

return msg;

}

}

SR为我们的每个字符串资源生成一个字段,这样方便您应用.net 的智能感知特性,也大大减少出错的机率。
字段内的实现方法都是调用Keys_SR类的GetString的方法。
SR类的内部的嵌入类Keys_SR,定义了一个ResourceManager字段,其构造方法为传入当前的资源的路径SampleApplication.MultiStrings.SR.srt和SR类所在的程序集名称,Keys_SR的GetString方法从资源文件中取出资源,GetString又直接转为调用resourceManager的GetString方法,资源的名称就是我们键入资源的名称,在这里,它为类的一个常量字段.

全部的秘密就在这里了。我们终于明白了它的原理。

在您的项目中应用StringResourceTool2

从网站上下载安装软件包,给您的项目添加字符串文件(string file),并且设置CustomTool为StringResourceTool2或SRT2

如果需要指定特定语种的资源文件,您可以这样设置

SR.strings

SR.strings-zh-cn

SR.strings-zh-tw

不要忘记设置为所有的字符串资源文件设置CustomTool=SRT2. 工具会从字符串文件中生成访问类,对于特定语言的字符串文件,工具将只生成资源文件,不生成访问类。
如果不熟悉不同国家的语种的名称,打开IE属性,ToolsàInternet Options, 在General标签页,点击Languages按钮,点击Add。
clip_image012
图六 语言和区域选项
如图,方括号中显示的就是所有国家的语种的简称。

string文件技巧

在我们下载回来的例子中,经常看到如下的内容:

# This file is used to generate SR.cs and SR.resx files. The copyright notice

# for those files appears here, in this SR.strings file.

# Options are specified as lines starting with "#!"

# Comments are lines starting with ";" or "#"

# To define the SR class public instead of internal (default):

##! accessor_class_accessibility = public

#! culture_info = Resources.CultureInfo

从上面的内容中,我们可以知道,注释以;或#开头 自定义选项以#!开头。
例如: # Comments 这是表示注释
#! accessor_class_accessibility = public 这一句把SR类默认的访问修饰符internal改为public

这个特性(feature)的好处很明显,我们可以把资源单独编译到一个程序集中,不与应用程序混合在一起,如新建立一个UIResx的项目,设置编译输出为Library. 并且用这个选项把SR类的访问修饰符为public. 这样,方便在其它应用程序中使用资源.

#! culture_info = Resources.CultureInfo 这一句表示设置区域为从当前的Resources的CultureInfo中读取
如果我们不希望运行时指定语言区域,这个选项可以让我们在编译时就指定当前语言区域。.

//下面的两行切换当前语种为简体中文

Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-cn");

Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("zh-cn");

此外,您可以把所有语种相关的资源放到一个字符串文件中,也可以把不同的语种相关的资源分布在不同的文件中。

如下的代码演示了把所有语种的字符串资源放到一个文件中。

[strings]

Raw = Raw string

StringArg(string name) = With name argument {0}

[strings.zh-cn]

Raw = 原始字符串

StringArg(string name) = 简体中文字符 {0}

您也可以按照如下的示例,把不同语种的字符串资源放到不同的文件中。

clip_image014

图七 把字符串放到到不同的文件中

当前默认语言的放到SR.strings文件中,简体中文的资源放到SR.strings-zh-cn文件中

总结

在与字符串有关的项目中,您可以充分发挥StringResourceTool2的能力,充分利用.net的智能感知技术,方便准确的构建您的应用程序。您可以通过查看代码详细了解它的用法。
在项目中比较推荐的作法,为您的项目创建一个只包含字符串资源的项目,设置输出为Library,方便您的维护和复用.

posted @ 2010-02-22 09:40  信息化建设  阅读(2848)  评论(4编辑  收藏  举报