Over a million developers have joined DZone.

Strongly Typed Localized Strings In Universal Apps

· DevOps Zone

The DevOps zone is brought to you in partnership with Sonatype Nexus. The Nexus suite helps scale your DevOps delivery with continuous component intelligence integrated into development tools, including Eclipse, IntelliJ, Jenkins, Bamboo, SonarQube and more. Schedule a demo today

Back in the old days when the need for localized string arose, I would add a new string and use AppResources to access the correct string in code.

In Windows Phone application (known today as Windows Phone Silverlight 8.0/8.1) I would do something like this:

public void SomeMethod()
    var localizedString1 = AppResources.MyFirstSring;
    var localizedString2 = AppResources.AnotherString;

In the new universal apps the story is a bit different:

  • Only strings are allowed in the resource files (which are .resw instead of .resx)
  • Using a directory for each supported language (i.e. Strings\en-US\)
  • Access to localized strings is string based

I can live with the first two (I actually prefer it that way) but I have huge problems withStringly Typed API calls – it’s easy to get it wrong, and even worse a trivial rename can cause problems that would only show during application run.

Luckily a co-worker of mine has put together a T4 template that fixes this problem (thanks Noam):

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Xml.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<# string str = this.Host.ResolvePath("strings\\en-us\\Resources.resw");
    System.Xml.Linq.XElement resXml = System.Xml.Linq.XElement.Load(str); // Read a data file here. "%aaa%/string/en-us/Resources.resw"
   IEnumerable<XElement> appElement = (from dataElements in resXml.Descendants("data") select dataElements); #>
using Windows.ApplicationModel.Resources;
namespace UniversalApp
    public class StringsResourceManager
        private static readonly ResourceLoader _resourceLoader = new ResourceLoader();
        public StringsResourceManager()
<# foreach (var element in appElement) { #>  
        public static string <#= element.Attribute("name").Value.Replace(".","_")#>  
                return _resourceLoader.GetString("<#= element.Attribute("name").Value#>");
<# } #>

Using the class created from this template I can get from this:

public void SomeMethod()
    var resourceLoader = new ResourceLoader();
    var string1 = resourceLoader.GetString("MyFirstSring");
    var string2 = resourceLoader.GetString("AnotherString");

To this:

public void SomeMethod() 
    var string1 = StringsResourceManager.MyFirstSring; 
    var string2 = StringsResourceManager.AnotherString; 

Happy coding...

The DevOps zone is brought to you in partnership with Sonatype Nexus. Use the Nexus Suite to automate your software supply chain and ensure you're using the highest quality open source components at every step of the development lifecycle. Get Nexus today


Published at DZone with permission of Dror Helper, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}