Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Localization .NET; Fallback language when using ResourceManager

Recently I was delving into Localization with .NET. Essentially, I learnt how to customize a form (using the Language and Localizable property) and then change the culture accordingly.

However, I found that when migrating my hard coded English strings into the auto-generated resource files, and use .GetString("Key") -- well, let's just say it wasn't happy :P.

I decided to make a separate set of resx files dedicated purely to the hard coded string translations. They followed the convention/requirement of [name].[culture-code].resx. I made of of these for each relevant language; e.g. appstrings.de.resx (For German) and appstrings.resx (as invariant baseline).

To utilise these new resources, I created an instance of ResourceManager and Resource Set

Dim resManager As New ResourceManager("LanguageTest.appstrings", Assembly.GetExecutingAssembly)
Dim resSet As ResourceSet = resManager.GetResourceSet(My.Application.UICulture, True, True)

The current UI culture was set (for example, to German) using

My.Application.ChangeUICulture("de")

Original issue

Unless the resSet.GetString("Key") is explicitly defined in the appstrings.de.resx, it will return a blank string. Is there anyway I can make it fallback to the appstrings.resx (where "Key" does exist), which I assumed would be the default baseline?

Update

Rhapsody made a suggestion below, while the actual tip itself didn't work, it did in-fact spark an interesting point, using resManager.GetString("Key") as opposed to resSet.GetString("Key"). This appears to work without flaw so far. That is, values present in the specialized language file are returned, while 'missing' values fall-back to the default culture when accessed by a single key.

Subsequent Issue

The only remaining issue would be whether the performance impact of using ResourceManger as opposed to a cached ResourceSet will be that detrimental?

like image 270
Jake Edwards Avatar asked Feb 16 '10 12:02

Jake Edwards


2 Answers

You can try declaring a default Culture for the application as below

[assembly: NeutralResourcesLanguageAttribute("en-US", UltimateResourceFallbackLocation.Satellite)]

This code declares that your default culture is en-US. In your example if current culture is "de-DE" it looks for for resource in "de-DE", then looks for the parent "de" culture and so on and Ultimatly goes to the defined culture (en-US) resource file. see MSDN for fallback strategies by resourceManage. The above code normaly goes in the assenblyInfo.cs. The second parameter is telling the resource manager where are the resources located in Main assembly or satellite.

Unfortunatly in this solution you have to use a culture name, Not the resource file name. however you could extend RM to use a specific resource by file name, But its way simpler to pick a default culture and rename your resource file to that culture and you have the solution out of the box.

like image 183
Moshiur Avatar answered Sep 21 '22 15:09

Moshiur


Try

Public Function GetString(ByVal Name As String) As String
    Return My.Resources.Strings.ResourceManager.GetString(Name)
End Function

Where Strings is the name of the resx files in your project. This will automatically return the baseline value when it's not available for the current culture.

It's an easy example, you might want to make it more fool proof.

like image 20
Rhapsody Avatar answered Sep 21 '22 15:09

Rhapsody