Using Satellite Assemblies for Multi-Language Programming, Page 2
Using External Resource Files
For our demo I created a text file containing some English text, the default for my laptop.
; This is my default resource file RES_WHAT=What time is it? RES_WHERE=Where is the train station?
I named the resource source file the same as my demo application's name, and compiled the default resource file with the following command line:
resgen InternationalizationDemo.txt InternationalizationDemo.resources
To use the external resource file we need to create an instance of the System.Resources.ResourceManager manager class, initializing the ResourceManager object with the resource type name and the Assembly containing the resource. A statement similar to the following works well.
Private Shared resourceManager As resourceManager = _ New resourceManager(GetType(Form1).Namespace + _ ".InternationalizationDemo", GetType(Form1).Assembly)
The member field is shared because only one instance is needed for all instances of the containing entity. The field is in the Form class, so we can get the namespace and the Form's containing assembly from the type object of the Form. GetType(Form1).Namespace + ".InternationalizationDemo" will build the resource type name correctly regardless of language the culture name, and GetType(Form1).Assembly will return the Form's assembly. For other applications substitute the Form1 parameter with the name of the class containing your ResourceManager field, and substitute the ".InternationalizationDemo" part with the file name part of your resource file.
After creating an instance of the ResourceManager we can request content anywhere we need to use the content. For example, if I want to display the What question then I could write resourceManager.GetString("RES_WHAT"), which would return the text "What time is it?" if we were running the application with the default culture settings of en-US.
Defining a Satellite Assembly
To define a satellite assembly, add a folder to your project containing the culture name for languages you'd like to support. For example, to support German we would add a folder named de-DE—case counts here. Next, add a file with the same prefix as your default file, a .txt suffix, and de-DE separated by a period in between. Placing this file in the proper folder would yield a Project Explorer that looks like the one shown in figure 1.
Figure 1: The demo application showing the default and German resource source and compiled resource files.
The figure shows the German language folder with the source text file and compiled resource file. We would add an addition folder for each language version we'd like our application to support. In addition, to the resources file we need to link our additional culture files into a DLL assembly—the default resource file is embedded into the application assembly—and we use the assembly linker to do this part.
We completed the first step by creating the culture specific sub-folder. The next step is to create the language version of the text file. If you just want to stub out the language text file append some additional text to a temporary file. Knowing enough German for our demo file I created the following German resource text file.
; This is the German version of the resource file RES_WHAT=Wie viel Uhr ist es? RES_WHERE=Wo ist der Bahnhof?
The next step is to compile the resource file using the resource generator. The command is almost identical to the previous example; all we need to do is substitute the file names to include the culture name in the file name.
resgen InternationalizationDemo.de-DE.txt InternationalizationDemo.de-DE.resources
Finally the following command shows how to use the assembly linker to embed the German resource into a satellite assembly that will be loaded when the culture name matches the German culture name, de-DE.
al /out:InternationalizationDemo.resources.dll /v:220.127.116.11 /c:de-DE /embed:InternationalizationDemo.de-DE.resources, InternationalizationDemo.InternationalizationDemo.de-DE.resources, Private
The last step is to test our satellite assemblies for each culture version we'd like to support.