Multiple language support is a very important thing to think of it in early software development process to avoid unnecessary work later on when we realize that we need it.
So how is it done?
There are several ways to support this and here I will describe one option supported in .NET framework using .resx files
In principle, it is possible to insert any text required resx file and then access it in the following way:
So instead of writing hard-coded strings, we will get them from resource. This approach suffers from several drawbacks.
To understand this, lets define some requirements that we want to support them:
- We want that localization will be loosely coupled with the app itself. Namely, to support other language or to change resource values (add / remove / change), we do not want to re-compile the application and to re-deploy.
- We want the ability to change a particular resource file reference. That is, if to a certain stage, to get the name of a vehicle, we go to Cars resource file, now we want to take values from a file called Vehicles.
- We want full control over access to the resource, so that we can add values that tried to get them and they were missing, we do validation on a new value, and the most important thing we can do Logging the missing value.
- We want one place to handle with everything. Debugging / maintenance
We can’t use the above approach and support all the above requirements.
To support this, we offer the following solution:
Resource project will be created one for each system. It will create a file for each module / subject or all the selected logical way.
We will create a resource file for each language we want to support it. The files should be marked as Access modifier = public.
We will define configuration file (xml). Each module name will be map to a file resource. So if we decide to go car name from “Vehicles” instead of “Cars”, we need to change only the name.
We will create a class (infrastructure) that will envelope the ResourceManager. it will keep a collection of resources as defined by the user in the configuration file.
In this class we will create a two methods, GetString and GetObject (for non-text resource).
We can add value to the resource file in case that does not exist and we can make sure this value is used as a key can actually be used as such. For example: “Some_key” This is the right value. However “some-key” is invalid.
And, of course, we can write logs.
The usage will be by sending the key and file name where the resource value should be:
MyResourceManager.GetString (key, CarsModuleResource);
CarsModuleResource will be as defined in the file config.
And from xaml we can call this method via MarkupExtension that will get the key and file name;
The XML config can be like this:
ResourceConfig Name="CarsModule" Path="Cars\Path.resx" Assembly="MyResorceAssembly.dll"