Once you’ve created your project, should you wish you distribute your software to multiple countries, then the question of localisation must, inevitably, arise. If you’re using .NET then a very tempting option is to use resource files. Most of the plumbing is already done for you, you simply need to create a resource file, and then localise it by copying the file and changing the extension to the correct culture.
Example
Say, for example, you had written your software in British English, and you wanted to localise to American English. Here’s you’re English version:
For an American version, copy the resource file:
Call the new file the same as the old one, but with the correct culture; for example:
Resource1.en-US.resx
And here’s some code to use the resource string in question:
[sourcecode langiage=“csharp”] static void Main( string[] args) { Console.WriteLine(Properties. Resource1.LocalString); }
Okay, so here's the brilliant thing about resources; that's it. When I change my culture it uses the culture specific resource file:
``` csharp
static void Main( string[] args)
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US" );
Console.WriteLine(Properties. Resource1.LocalString);
}
So - what’s new?
It’s pretty likely that you’ve already seen that part. You may also have seen the next part too - but my guess is that if you’ve read this long, you haven’t.
Centralise resources
In the above project, having a resource file and just accessing it seems to make a lot of sense, but what if there’s more than one project; what if you have a solution with a few projects?
You could have a resource file for each project, and that works. But, what if you decide to translate to French, but no-one on your team speaks fluent (and it does have to be fluent) French? There are LOTS of companies that will accept a resource file and translate - they’ll also accept several, and translate them all, but why make it so that you need several?
Centralised resources in action
Create a new class library in the following vein:
[sourcecode langiage=“csharp”] namespace Localise { public class Localise { private static ResourceManager _resourceMan;
private static ResourceManager ResourceMan
{
get
{
if (\_resourceMan == null)
{
ResourceManager tmpRes = new ResourceManager("Localise.Localise.Properties.Resources" , typeof(Resources ).Assembly);
\_resourceMan = tmpRes;
}
return \_resourceMan;
}
}
public static string GetResString( string key)
{
string valString = ResourceMan.GetString(key);
return valString;
}
}
}
If you've ever had a look at the resources.designer.cs then this code should look very familiar. That of course is internal, so doesn't work for this.
All your resources now go in here, and you simply reference it from your project like so:
``` csharp
Console.WriteLine(Localise.Localise.GetResString("LocalString"));
Conclusion
There are other ways to handle resource strings - you can hold them in the database, in text files, you could build a whole infrastructure of resource assets. If you have a massive solution distributed to hundreds of countries then that’s probably worth it. If not, use what Microsoft give you for free.