Globalization and localization in ASP.NET Core – Part 3

If you just landed on this page, this page is of series of Post for localization / globalization

Part 1 – Introduction

Part 2 – ASP.NET Core ways of Localization / Globalization

Part 3 – Old trustworthy ResourseManager

If you are following the series of post, in this post, I would talk about working with ResourceManager.

ResourceManager class is nothing new, It been there since the inception of .NET framework. It was the de facto mechanism for working with localize resource file before aspnet core introduce IStringLocalizer.

In this post, I want to demonstrate, ResourceManager still works in dotnet core, if you don’t want to go with fuzzy IStringLocalizer.

Let dive in to the code, in the sample application, you fill find two methods in HelloController. In Local method

 string rsFileName = "api1.Resources.rs1";
 ResourceManager rm = 
       new ResourceManager(rsFileName, Assembly.GetExecutingAssembly());
 string msg = rm.GetString("Hello");

Here, it creating new instance of the ResourceManager which take basename and assembly where these resource files are embedded.

Basename is the root name of the resource file without its extension but including any fully qualified namespace name. For example, the root name for the resource file named
MyApplication.MyResource.en-US.resources is MyApplication.MyResource.

Assembly needs to be the one where resource files are embedded. In our case it is same as the one where running code (HelloController) is present. I can get current assembly which contains the code by Assembly.GetExecutingAssembly() which returns api1.dll assembly

In our case, resources file which ResourceManager will read are name rs1.resx and placed in “Resources” folder. Hence, basename will be api1.Resources.rs1

ResourceManager.GetString will looks for current culture on running thread and respectively look for culture specific resource file to get the value of key “Hello”


If culture specific resource is not found, say “de-de“, it will use default resource with any suffix for getting the value of the “key“. If “key” values isn’t found in the resource file, it will return value as “key” itself.

If you need to get resource value for any other culture than the current culture on the running tread, you can by specifying the culture in the GetString method.

string msg3 = rm.GetString("Hello", new System.Globalization.CultureInfo("fr-FR"));

As simple as that.

Now, level 2. I had requirement where code for reading resource was in another assembly/dll then the one where resource files are located.

If you look into the lib method, it calls Lib1.ResRdr library to get the resource file message. But, rs1.resx is in api1.dll, not in Lib1.Rdr.dll

 public string lib()
   string msg = "";
   msg = Lib1.ResRdr.Messenger.GetHello(); 
   return msg;

If you look into GetHello() method

public static string GetHello()
   string msg = "";
   Assembly asm = Assembly.GetCallingAssembly();
   string rsFileName = asm.GetName().Name + ".Resources.rs1";
   ResourceManager rm = new ResourceManager(rsFileName, asm);
   var msg2 = rm.GetString("Hello");
   msg = msg2;
   return msg;

It creates new ResourceName, pass the basename and assembly which contains the embedded resource. Since, it seperate dll, it get’s the calling assembly by Assembly.GetCallingAssembly() which would return api1.dll or api2.dll, whichever calls  Lib1.Rdr.dll. Note, here if you had use Assembly.GetExecutingAssembly(), you will get Lib1.Rdr.dll.

For the basename, since resources are embedded in the dll, assembly root namespace needs to be taken from the assembly name. i.e. api1, api2. So, basename would be api1.Resources.rs1 or api2.Resources.rs2

Rest would be taken care by the ResourceManager, it would read remote assembly embedded resources and it’s satellite assemblies to get the translated value.

That’s all for Globalization and localization in ASP.NET Core. Hope you find this series of post informative.


2 thoughts on “Globalization and localization in ASP.NET Core – Part 3

  1. Pingback: Globalization and localization in ASP.NET Core – Part 2 | Technical Insanity

  2. Pingback: Globalization and localization in ASP.NET Core – Part 1 | Technical Insanity

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s