Click here to Skip to main content
15,878,871 members
Articles / Programming Languages / C#

How to make the usage of textual resources in .NET easy and robust to become

Rate me:
Please Sign up or sign in to vote.
4.45/5 (8 votes)
2 Aug 2004CPOL4 min read 49.7K   231   25   7
The given article is for developers of components for .NET platform, which support internationalization. The article will also be useful for those who are working with .NET, using resource files and functions like String.Format.

The example of the task used for demonstration

We have a Windows Forms application, which must support three languages: English, Italian, and Russian. So, in the status bar of the application, the following string should be printed: "Date: {current date}", in the language of the user's locale.

The solution given by Microsoft

Microsoft recommends to do the following:

  1. Create one .resx file for each of the language supported for storing the text resources.
  2. Add in each of the files, a string with a common resource identifier, for example, "IDS_DATE", with the text written using the proper language. For example, for the English version, the text will be "Date: {0}".
  3. Write the code like the following:
    C#
    string messageTemplate = resourceManager.GetString( "IDS_DATE" );
    string finalMessage = string.Format( messageTemplate, new DateTime() );
    // Update the text in the status bar.

Note

It is possible to find the information about the usage of resources in .NET. For example, here.

It seems that everything is OK but let's look at the code more attentively:

  1. If to change the name of the identifier in the resources or if there is a mistake in writing of this name in the code, the compiler does not report about any error, as in the code the name is stored as a string.
  2. Often the textual resources are the templates of the messages. These templates contain some parameters, and as the templates are declared in a separate file, it creates an additional risk of the fact that the number or the sequence of the parameters during the formatting of the template will be incorrect.

ResxWrap as the tool for resolving such problems

The tool ResxWrap - the generator of class-wrappers for textual resources from .resx files - was created for resolving this type of problems. The class-wrappers give the user the possibility to work with resources in a much more convenient manner. For the above example, it would be enough to write:

C#
string finalMessage = generatedWrapper.IDS_DATE( new DateTime() );
// Update the text in the status bar.

What doest it change?

  1. Instead of two lines of code, we have only one. It is not bad to reduce twice the amount of the routine code.
  2. If the name of the identifier is changed, we are safe now, as the compiler will report about an error, because the class-wrapper will not contain any more, the method IDS_DATE.
  3. If we change the number of arguments in the textual template "IDS_DATE", it will not also be a problem. The compiler will give us again a message about an error, as the signature of appropriate method of the class-wrapper will be changed as well.
  4. While editing the call of the method, it is possible to look at the reference for every parameter to be sure that the sequence is correct.

How to generate the class-wrapper

ResxWrap is a tool managed by command line arguments. Returning to our example, having supposed that our project has the namespace by default "SampleApp", the files of the project are located in the directory "C:\My Projects\SampleApp", and the file of resources is called "StringTable.resx". So, for generating the class-wrapper, it will be enough to launch the tool with the following arguments:

C#
ResxWrap SampleApp "C:\My Projects\SampleApp\" StringTable

When generating is over, in the directory of the project, a new file will appear named "__StringTable.cs", which will contain a definition of the class with the same name and declared in the same namespace.

Of course, it is also possible to write a .bat file, and every time after changing in "StringTable.resx" to launch the generation again, but for safety, it is better to add one line in Pre-build Event Command Line in the settings of the project. For this, it is enough to write in the case of our example:

ResxWrap SampleApp ${ProjectDir} StringTable

Let's look inside

The generated class contains:

  1. The constructor for the initialization of the protected field of the type System.Resources.ResourceManager;
  2. Read-only static fields with the names for each identifier of the resource declared in .resx file;
  3. The methods and read-only properties, returning textual values for every resource.

If the textual string contains parameters, then the signature of the method will contain the appropriate number of parameters accompanied with documentation comments. The body of the method besides the loading of the template of the textual message will also contain the call of String.Format preparing the final version of the message.

Resume

So, if you have decided to use ResxWrap tool for development of a project, you must:

  1. Add a call of the tool ResxWrap in the file of the project;
  2. Recompile the project;
  3. Add the generated file of the class-wrapper to the list of the project files;

  4. Create an instance of the class-wrapper;
  5. Call the appropriate method or property for extracting necessary textual resources.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Switzerland Switzerland
* 20 years in software development;
* 15 years in financial services;
* 2 master degrees: in IT and Quantitative Finance;
Specialisations: back-end software development (C#, C++, Java), Oracle.

Comments and Discussions

 
GeneralI missed the C resource value checks. Pin
DavidDunning11-Aug-04 7:20
DavidDunning11-Aug-04 7:20 
GeneralNot all true Pin
Heath Stewart5-Aug-04 6:36
protectorHeath Stewart5-Aug-04 6:36 
GeneralRe: Not all true Pin
Yury Fedorov6-Aug-04 0:12
Yury Fedorov6-Aug-04 0:12 
GeneralRe: Not all true Pin
Heath Stewart6-Aug-04 1:26
protectorHeath Stewart6-Aug-04 1:26 
GeneralRe: Not all true Pin
Yury Fedorov6-Aug-04 2:12
Yury Fedorov6-Aug-04 2:12 
GeneralRe: Not all true Pin
Member 969-Aug-04 17:56
Member 969-Aug-04 17:56 
GeneralRe: Not all true Pin
jaxterama29-Aug-04 8:03
jaxterama29-Aug-04 8:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.