swirl
Home Software Blog Wallpapers Webtools
Localization in DotNet via a simple example
Saturday 29, July 2017   |   Post link   |   Sample code  Download related material

When it comes to application development, localization is perhaps the few things we do every day without even thinking. Most products / projects will have their own well defined way to localize information. I'll recap the basic localization support DotNet offers via a simple console application.

Localization is provided by bundling all language specific information into a single assembly known as a sattelite assembly. A sattelite assembly is build for each language we want to support. Visual Studio has very good support for building localized content and generating the sattelite assemblies by itself.

In this post, we'll look at two samples; one where we use Visual Studio to do everything and second where we will use AssemblyLinker (al.exe) to generate the satellite assemblies by hand. In both samples, we'll support three languages: neutral, en-IN and en-GB. The neutral language resources will be used whenever the application is run on a system whose language does not match any of the two languages (en-IN and en-GB).

Sample 1 - Using Visual Studio for everything

Step 1

Create a new command line application project named 'localized' using Visual Studio

Step 2

Create a folder called Resources at the root of the project, this for helping us keep resource files together and avoid clutter.

Step 3

In Visual Studio, right click on the Resources folder and select Add -> New Item and select Resources file. Name the file Strings.resx - this is going to be the default resource file.

New resource file

Similary add another one named 'Strings.en-in-resx' and another one named 'Strings.en-gb-resx'.

Double-click the String.resx file and enter a string named 'Greeting' with value 'How are ya?'. Similarly, open the Strings.en-in.resx file and enter a string with the same name 'Greeting' and value 'Namaste!'. Do the same for Strings.en-gb.resx and use the value 'How are you?'.

Ensure the build action for all the resx files is set to 'Embedded Resource'; this can be see in the properties window.

Step 4

Build the project once to see everything builds OK. Open the Program.cs file and edit the code to match:

using localized.Resources;
using System;
using System.Globalization;
using System.Threading;

namespace localized
{
	class Program
	{
		static void Main(string[] args)
		{
			Print();

			// Lets switch our language
			Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-in");
			Print();

			// Lets switch our language again
			Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-gb");
			Print();
		}

		static void Print()
		{
			Console.WriteLine("You say '{0}' in {1}", Strings.Greeting, Thread.CurrentThread.CurrentUICulture);
		}
	}
}

Run the application to view the output.

Sample1 Output

As you can see, a different greeting is printed for each language.

If you inspect the bin\debug folder, you'll see the exe as well as a folders named en-IN & en-GB. These folders contain the resource dll for the respective language. In the next example, we'll build the resource dlls ourself. The whole languages support works on the basis of placing the resource dlls in the correct language folders.

Sample 2 - Building the resource dlls ourself

Step 1

Copy the entire project folder of sample 1. After copying, rename the project file in the new copy to localized2.csproj and add it to the solution. This is just so that we don't need to retype all the strings we defined in the last project. Since we don't want Visual Studio's help to build the resource dlls, select the Strings.en-gb.resx and Strings.en-in.resx and set the 'Build Action' in the properties windows to 'None'. Rebuild the project and run it, you should see only the default language greeting string for all the languages. Note, we are string building the Strings.resx as an embedded resource so that it will be available within the exe; this is a good practice to have the neutral culture resource in the main assembly.

Step 2

Start the Developer Command Prompt for Visual Studio and navigate to the project folder. In the command prompt type in 'notepad build-resources.bat' & enter the following content and save the file.

resgen Resources\Strings.en-in.resx Resources/localized.Resources.Strings.en-in.resources
md bin\debug\en-in
al /t:lib /culture:en-in /embed:Resources/localized.Resources.Strings.en-in.resources /out:bin\debug\en-in\localized.resources.dll

resgen Resources\Strings.en-gb.resx Resources/localized.Resources.Strings.en-gb.resources
md bin\debug\en-gb
al /t:lib /culture:en-gb /embed:Resources/localized.Resources.Strings.en-gb.resources /out:bin\debug\en-gb\localized.resources.dll	

What we have here are the commands to compile the resources in the resx to a resource file using the resgen utility. The next utlity al (assembly linker) is used to build an assembly out of the binary resource file and while doing so also mark the culture-information against the assembly.

Run this batch file from the project folder where you have the localized2.csproj file. The output should look something like this:

Build assemblies

Build the actual project. Running the application should give you the same output as the first.

So there you have it - building plain vanilla resource dlls using Visual Studio and using DotNet's SDK tools.

Sample code  Download related material

Categories: C# (3) DotNet (3)

Comments

Posts By Year

2024 (4)
2023 (5)
2022 (10)
2021 (5)
2020 (12)
2019 (6)
2018 (8)
2017 (11)
2016 (6)
2015 (17)
2014 (2)
2013 (4)
2012 (2)

Posts By Category

.NET (4)
.NET Core (2)
ASP.NET MVC (4)
AWS (5)
AWS API Gateway (1)
Android (1)
Apache Camel (1)
Architecture (1)
Audio (1)
Azure (2)
Book review (3)
Business (1)
C# (3)
C++ (2)
CloudHSM (1)
Containers (4)
Corporate culture (1)
Database (3)
Database migration (1)
Desktop (1)
Docker (1)
DotNet (3)
DotNet Core (2)
ElasticSearch (1)
Entity Framework (3)
Git (3)
IIS (1)
JDBC (1)
Java (10)
Kibana (1)
Kubernetes (1)
Lambda (1)
Learning (1)
Life (7)
Linux (2)
Lucene (1)
Multi-threading (1)
Music (1)
OData (1)
Office (1)
PHP (1)
Photography (1)
PowerShell (2)
Programming (28)
Python (1)
Rants (5)
SQL (2)
SQL Server (1)
Security (3)
Software (1)
Software Engineering (1)
Software development (2)
Solr (1)
Sql Server (2)
Storage (1)
T-SQL (1)
TDD (1)
TSQL (5)
Tablet (1)
Technology (1)
Test Driven (1)
Testing (1)
Tomcat (1)
Unit Testing (1)
Unit Tests (1)
Utilities (3)
VC++ (1)
VMWare (1)
VSCode (1)
Visual Studio (2)
Wallpapers (1)
Web API (2)
Win32 (1)
Windows (9)
XML (2)

Posts By Tags

.NET(6) API Gateway(1) ASP.NET(4) AWS(3) Adults(1) Advertising(1) Android(1) Anti-forgery(1) Asynch(1) Authentication(2) Azure(2) Backup(1) Beliefs(1) BlockingQueue(1) Book review(2) Books(1) Busy(1) C#(4) C++(3) CLR(1) CORS(1) CSRF(1) CTE(1) Callbacks(1) Camel(1) Certificates(1) Checkbox(1) Client authentication(1) CloudHSM(1) Cmdlet(1) Company culture(1) Complexity(1) Consumer(1) Consumerism(1) Containers(3) Core(2) Custom(2) DPI(1) Data-time(1) Database(4) Debugging(1) Delegates(1) Developer(2) Dockers(2) DotNetCore(3) EF 1.0(1) Earphones(1) Elastic Search(2) ElasticSearch(1) Encrypted(1) Entity framework(1) Events(1) File copy(1) File history(1) Font(1) Git(2) HierarchyID(1) Hyper-V(1) IIS(1) Installing(1) Intelli J(1) JDBC(1) JSON(1) JUnit(1) JWT(1) Java(3) JavaScript(1) Kubernetes(1) Life(1) LinkedIn(1) Linux(2) Localization(1) Log4J(1) Log4J2(1) Logging(1) Lucene(1) MVC(4) Management(2) Migration history(1) Mirror(1) Mobile Apps(1) Modern Life(1) Money(1) Music(1) NGINX(1) NTFS(1) NUnit(2) OData(1) OPENXML(1) Objects(1) Office(1) OpenCover(1) Organization(1) PHP(1) Paths(1) PowerShell(2) Processes(1) Producer(1) Programming(2) Python(2) QAAC(1) Quality(1) REDIS(2) REST(1) Runtimes(1) S3-Select(1) SD card(1) SLF4J(1) SQL(2) SQL Code-first Migration(1) SSH(2) SSL(1) Sattelite assemblies(1) School(1) Secrets Manager(1) Self reliance(1) Service(1) Shell(1) Solr(1) Sony VAIO(1) Spirituality(1) Spring(1) Sql Express(1) System Image(1) TDD(1) TSQL(3) Table variables(1) Tables(1) Tablet(1) Ubuntu(1) Url rewrite(1) VMWare(1) VSCode(1) Validation(2) VeraCode(1) Wallpaper(1) Wallpapers(1) Web Development(4) Windows(2) Windows 10(2) Windows 2016(2) Windows 8.1(1) Work culture(1) XML(1) Yii(1) iTunes(1) open file handles(1) renew(1) security(1) static ip address(1) ulimit(1)