65.9K
CodeProject 正在变化。 阅读更多。
Home

关于 C# .Net 辅助程序集的全部信息

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (20投票s)

2014 年 7 月 30 日

CPOL

8分钟阅读

viewsIcon

58781

downloadIcon

701

了解、创建和使用 C# .Net 中的辅助程序集

引言

本文详细介绍了在使用辅助程序集之前您必须了解和掌握的所有基础知识。本文假设读者已具备使用 Visual Studio 编辑器进行 C# 编程的先验知识。

背景

在当今时代,我们创建的应用程序面向多种国家、语言和文化。英语是一种全球语言,但每个国家都有其通用的地方语言。当您为遍布全球的客户构建应用程序时,很有可能他们希望您用他们所在国家/地区的各种本地语言编写应用程序。您的客户期望的是对应用程序进行本地化,也就是说,如果他在北京打开您的应用程序,用户界面应该显示中文;如果他在沙特阿拉伯的利雅得打开应用程序,应该显示阿拉伯语;如果他在美国打开应用程序,应该显示英语,依此类推。对于 Windows 窗体应用程序,我们想到的最简单的解决方案可能是用所有支持的语言编写应用程序的每个窗体,并通过检测应用程序运行的区域设置来加载相应的窗体。显然,由于以下原因,这效率非常低下:

  1. 可维护性问题:代码膨胀。您必须为每种支持的语言维护三个文件(实际上是每个窗体的 .designer.cs 分部文件,共六个)。每次需要支持新语言时,都必须为每个窗体添加一个新的特定语言的设计器文件。
  2.  部署麻烦:每次需要支持新语言时,我都必须重新构建并重新部署整个应用程序,因为源代码发生了变化。对于安装在全球多个地点的庞大产品来说,这种情况可能是一场噩梦。
  3. 漫长的开发过程:核心 C# 开发人员和语言翻译人员始终是不同的人。语言翻译人员总是不得不等待开发人员完成他们的工作,之后他们才能进行翻译工作。这在开发周期中会浪费大量时间。

别担心,.Net 中的辅助程序集可以为您解忧。让我们开始了解它的基本概念。

辅助程序集基础知识

语言:任何口头/书面交流方式都是语言。例如,英语、中文、阿拉伯语。

区域设置:.Net 将世界的特定区域识别为区域设置。.Net 为世界的每个区域分配唯一的 ID,如以下链接所示:

http://msdn.microsoft.com/en-us/library/ms912047(v=winembedded.10).aspx

文化:.Net 中的每种文化都由主要和次要标签标识。主要标签指语言,次要标签指它所代表的区域设置。例如,“en-US”代表美国区域设置的英语。“ar-SA”代表在沙特阿拉伯区域设置中使用的阿拉伯语。

本地化和全球化:我将留给您在此 MSDN 链接中探索这些术语的定义:

http://msdn.microsoft.com/en-us/library/aa292205(v=vs.71).aspx

辅助程序集:包含仅包含特定区域设置资源的 .Net 程序集称为辅助程序集。这些程序集不包含您的 C# 代码或任何编程逻辑。它们仅包含本地化资源,如文本、图像、图标、音频或其他应用程序中使用的类似内容。对于您希望在应用程序中支持的每种文化,您都会创建一个单独的辅助程序集,其中包含该特定文化的本地化资源。例如,如果我想让我的应用程序支持沙特阿拉伯语和印地语两种语言,那么我的应用程序部署时总共会有以下三个程序集:

  1. 一个用于“ar-SA”文化的辅助程序集。
  2. 一个用于“hi-IN”文化的辅助程序集。
  3. 一个包含所有 C# 代码和逻辑的主程序集。主程序集应始终保持区域设置中立。默认语言(回退)资源始终存在于主程序集中。您的 AssemblyInfo.cs 文件应具有以下声明,使其成为区域设置中立程序集:

[assemblyAssemblyCulture("")]

使用代码

让我们为我们打算在应用程序中支持的两种语言之一创建辅助程序集。我在演示应用程序中使用 Visual Studio 2010 作为开发工具,并使用 C# 作为编程语言。我打算本地化我的应用程序的用户界面,如下所示:

开发步骤

  1. 在“已安装模板”->“Visual C#”->“Windows”下,创建一个名为“TestSatelliteAssembly”的新项目,模板为“Windows 窗体应用程序”。

          默认情况下,Visual Studio 会为您的应用程序的默认(回退)语言创建一个名为“Resources.resx”的资源文件,如下面的红色框所示。此资源始终包含在主程序集“TestSatelliteAssembly.dll”中。

  1. 在深入 C# 编码之前,您需要执行以下操作:                                                               i) 在解决方案中创建一个名为“Resources”的新文件夹。
    ii) 将“Resource.resx”文件从“Properties”文件夹移动到“Resources”文件夹。
    iii) 将“Resources.resx”文件重命名为“LocalizedResources.resx”。
    iv) 现在,在文件夹内,添加一个新项。在项目文件的右键菜单中,转到“添加”->“新建项”向导。在“Visual C# 项”->“常规”下选择“资源文件”项。将新添加的文件命名为“LocalizedResources.hi-IN.resx”。
    v) 在“LocalizedResources.hi-IN.resx”资源文件中,以键值对的形式为我们打算本地化的两个控件添加本地化字符串。下面的快照给出了详细信息,相关部分用红色框标记:
  2. 现在我们需要编写以下代码,它充当 Windows 窗体和针对印地语的资源文件之间的粘合剂。以下是来自相应文件的代码片段,供您参考。我添加的额外代码用斜体标出,以引起您的注意。

Main.cs 文件源代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Globalization;
using System.Threading; 

namespace TestSatelliteAssembly
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            CultureInfo newCultureInfo = new System.Globalization.CultureInfo("hi-IN");
            Thread.CurrentThread.CurrentCulture = newCultureInfo;
            Thread.CurrentThread.CurrentUICulture = newCultureInfo; 
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

您必须为 Form1.cs 中存在的窗体定义“Form_Load”事件。如下所示修改“Form1_Load”方法内的相应事件处理程序代码。我添加的额外代码用斜体标出,以引起您的注意。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Resources;
using System.Reflection; 

namespace TestSatelliteAssembly
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
	
            LoadLocalizedResources();
        }
	
        private void LoadLocalizedResources()
        {
            ResourceManager resourceManager = new ResourceManager("TestSatelliteAssembly.Resources.LocalizedResources",(Form1).Assembly);
            //Equivalent statement for above
            //ResourceManager resourceManager = new ResourceManager("TestSatelliteAssembly.Resources.Localiz           //edResources",Assembly.GetExecutingAssembly());
            label1.Text = resourceManager.GetString("lblUserNameText");
            button1.Text = resourceManager.GetString("btnSubmitText");

        }
    }
}

然后一切就绪。只需运行 Ctrl+F5 即可看到本地化的 UI,如下所示:

幕后发生了什么

这是幕后发生的情况。看看您项目目录的 obj -> Debug 文件夹。我在红色框中突出显示的资源文件实际上是 Visual Studio 转换的二进制文件,对应于我们项目中的两个资源 (*.resx) 文件,即一个用于默认资源,另一个用于印地语资源。

您还可以注意到“hi-IN”文件夹,它看起来如下所示。这里,“TestSatelliteAssembly.resources.dll”文件就是我们一直谈论的辅助程序集。它不包含 C# 代码,而是嵌入了印地语资源文件“TestSatelliteAssembly.Resources.LocalizedResources.hi-IN.resources”。如果您检查 bin -> debug 文件夹的内容,您会注意到此辅助程序集也会被部署。Bin->Debug 文件夹在“hi-IN”文件夹内包含辅助程序集。 "*.resx" 或 "*.resources" 文件从不部署。

我们的问题是如何解决的

让我们快速回顾一下我们最初的问题以及它们是如何在此得到解决的:

  1. 本地化的资源字符串现在存在于单独的物理资源文件中,进而存在于单独的物理辅助程序集中。我们不必为同一个视图维护多个窗体。通过从相应的辅助程序集设置本地化文本,可以加载您选择的语言的相同窗体。
  2. 每次我们需要支持新文化时,只需为该文化构建一个新的辅助程序集并进行部署。现在不再需要为了支持新语言而重新构建和部署整个应用程序。
  3. 由于包含特定区域设置字符串的资源文件存在于单独的物理文件中,因此可以与开发工作并行地将其交给语言专家。一旦开发工作完成,我们只需集成资源文件即可生成最终版本。

关注点

您还可以探索以下更多内容:

  1. 目前,我希望加载应用程序的文化在我的 main.cs 文件中是硬编码的。如何使其在运行时动态化?
  2. 将应用程序扩展到您选择的语言。
  3. .Net 中的不变量文化是什么?
  4. 您也可以将资源文件创建为“*.xml”或“*.txt”文件。如何做到?
  5. 如何使用程序集链接器(AL.exe)工具链接辅助程序集。
  6. 探索 Visual Studio 提供的 resgen 工具,将“*.resx”文件转换为“*.resources”文件。
  7. 探索您可以在 AssemblyInfo.cs 文件中放置的以下属性,以定义您选择的默认/回退区域设置:

    [assemblyNeutralResourcesLanguage("en-US",UltimateResourceFallbackLocation.Satellite)]

历史

修复了快照链接。

 

© . All rights reserved.