Resourcemanager is returning same resource, although CultureInfo is specified

Jochen van Wylick picture Jochen van Wylick · Jun 30, 2012 · Viewed 14.1k times · Source

A very simple thing, and I can't get it to work. I want to globalise my dll thus I'm using resource files + the ResourceManager.

I call the resourcemanager like this:

var p = new ResourceManager("Appname.Default", Assembly.GetExecutingAssembly());

Get the strings like this

System.Diagnostics.Debug.WriteLine(p.GetString("greeting"));
System.Diagnostics.Debug.WriteLine(p.GetString("greeting", new CultureInfo("nl")));
System.Diagnostics.Debug.WriteLine(p.GetString("greeting", new CultureInfo("nl-NL")));
System.Diagnostics.Debug.WriteLine(p.GetString("greeting", new CultureInfo("en")));

And it returns 4 times the same string. My files are called

Default.resx 
Default.en.resx 
Default.nl.resx 
Default.nl-NL.resx

All file settings are the same, but as mentioned - only the resource in the Default file is used.

What am I overlooking here?

Answer

CodeCaster picture CodeCaster · Jun 30, 2012

There are a few ways of using resource files, one of which is using .resx files. These files get localized automatically, based on the value of Thread.CurrentThread.CurrentUICulture. The default .resx file gets compiled into the assembly it is part of (for example your main executable), while the localized resources (Default.nl-NL.resx) get compiled into their own directory (based on the culture identifier, nl-NL in this case) into an assembly, called <AssemblyName>.resources.dll.

Addressing values from those resources is as easy as <ResourceName>.<KeyName>, for example Default.Greeting. To test it, you change the culture, using:

Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
Console.WriteLine(Default.Greeting);

Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("nl-NL");
Console.WriteLine(Default.Greeting);

Which will output

Hello
Hallo

On program startup, the UI Culture is set to the culture of the computer it's running on, so you won't have to specify the language yourself to always present the localized resources. So, .resx files seem the way to go.

When using the ResourceManager from var p = new ResourceManager("Appname.Default", Assembly.GetExecutingAssembly());, you will have to read .resources files. If there is no (in your case) Appname.Default.resources file, the p.GetString will fail. So I guess you have created one .resources file earlier, but haven't converted the localized .resx files to .resources files.

If you want to use the ResourceManager to be able to specify the culture, you can use:

Default.ResourceManager.GetString("Greeting", new CultureInfo("en-US"));