I'll soon be working on a large c# project and would like to build in multi-language support from the start. I've had a play around and can get it working using a separate resource file for each language, then use a resource manager to load up the strings.
Are there any other good approaches that I could look into?
Standard resource files are easier. However, if you have any language dependent data such as lookup tables then you will have to manage two resource sets.
I haven't done it, but in my next project I would implement a database resource provider. I found how to do it on MSDN:
http://msdn.microsoft.com/en-us/library/aa905797.aspx
I also found this implementation:
DBResource Provider
Use a separate project with Resources
I can tell this from out experience, having a current solution with
1224 projects that includes API, MVC, Project Libraries (Core functionalities), WPF and Xamarin. It is worth reading this long post as I think it is the best way to do so. With the help of VS tools easily exportable and importable to sent to translation agencies or review by other people.EDIT 02/2018: Still going strong, converting it to a .NET Standard library makes it possible to even use it across .NET Framework and NET Core. I added an extra section for converting it to JSON so for example angular can use it.
EDIT: 2019: Going forward with Xamarin, this still works across all platforms. E.g. Xamarin.Forms advices to use resx files as well. (I did not develop an app in Xamarin.Forms yet, but the documentation, that is way to detailed to just get started, covers it: Xamarin.Forms Documentation). Just like converting it to JSON we can also convert it to a .xml file for Xamarin.Android (currently working on).
So, lets get to it.
Pro's
ResourceDirectories
.Thread.CurrentThread.CurrentCulture
Con's
Setup
Create language project in your solution, give it a name like MyProject.Language. Add a folder to it called Resources, and in that folder, create two Resources files (.resx). One called Resources.resx and another called Resources.en.resx (or .en-GB.resx for specific). In my implementation, I have NL (Dutch) language as the default language, so that goes in my first file, and English goes in my second file.
Setup should look like this:
The properties for Resources.resx must be:
Make sure that the custom tool namespace is set to your project namespace. Reason for this is that in WPF, you cannot reference to
Resources
inside XAML.And inside the resource file, set the access modifier to Public:
Using in another project
Reference to your project: Right click on References -> Add Reference -> Prjects\Solutions.
Use namespace in a file:
using MyProject.Language;
Use it like so in back-end:
string someText = Resources.orderGeneralError;
If there is something else called Resources, then just put in the entire namespace.Using in MVC
In MVC you can do however you like to set the language, but I used parameterized url's, which can be setup like so:
RouteConfig.cs Below the other mappings
FilterConfig.cs (might need to be added, if so, add
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
to theApplication_start()
method inGlobal.asax
LocalizationAttribute
LanguageHelper just sets the Culture info.
Usage in .cshtml
or if you don't want to define usings then just fill in the entire namespace OR you can define the namespace under /Views/web.config:
This mvc implementation source tutorial: Awesome tutorial blog
Using in class libraries for models
Back-end using is the same, but just an example for using in attributes
If you have reshaper it will automatically check if the given resource name exists. If you prefer type safety you can use T4 templates to generate an enum
Using in WPF.
Ofcourse add a reference to your MyProject.Language namespace, we know how to use it in back-end.
In XAML, inside the header of a Window or UserControl, add a namespace reference called
lang
like so:Then, inside a label:
Since it is strongly typed you are sure the resource string exists. You might need to recompile the project sometimes during setup, WPF is sometimes buggy with new namespaces.
One more thing for WPF, set the language inside the
App.xaml.cs
. You can do your own implementation (choose during installation) or let the system decide.Using it in Angular (convert to JSON)
Now days it is more common to have a framework like Angular in combination with components, so without cshtml. Translations are stored in json files, I am not going to cover how that works, but if you want to convert this to a JSON file, it is pretty easy, I use a T4 template script that converts the Resources file to a json file. I recommend installing T4 editor to read the syntax and use it correctly because you need to do some modifications.
Only 1 thing to note: It is not possible to generate the data, copy it, clean the data and generate it for another language. So you have to copy below code as many times as languages you have and change the entry before '//choose language here'. Currently no time to fix this but probably will update later (if interested).
Path: MyProject.Language/T4/CreateWebshopLocalizationEN.tt
There you go, you can now use one single resource file for all your projects. This makes it very easy exporting everything to an excl document and let someone translate it and import it again.
I'd go with the multiple resource files. It shouldn't be that hard to configure. In fact I recently answered a similar question on setting a global language based resource files in conjunction with form language resource files.
Localization in Visual Studio 2008
I would consider that the best approach at least for WinForm development.
We use a custom provider for multi language support and put all texts in a database table. It works well except we sometimes face caching problems when updating texts in the database without updating the web application.