I think you can rely heavily on the resource infrastructure provided by .NET with a few changes to make it more suitable for large projects, namely to create and maintain resources independent of the application and to eliminate the generated properties that apply to each resource by name. If there are other objectives suitable for large project localization that are not discussed below, describe them so that I can consider them.
- Create a stand-alone project to represent your resources, which can be loaded as a separate DLL.
- Add the “Resources” file to the project by selecting the link on the “Resources” tab of the project properties: “This project does not contain the default resource file. Click here to create it.”
- Add another resource with the same root name to represent another language, for example, "Resource.de.resx" for German. (Visual Studio apparently uses the file name to determine the language that the resource file represents). Move it to the same directory / folder as the default resource file. (Repeat for each language.)
- In the properties of the Resources.resx file, remove the "ResXFileCodeGenerator" from the Custom Tool property to prevent the generation of default code in the namespace of the Properties application. (Repeat for each language.)
Explicitly / manually declare your own resource manager, which loads the newly created resources using a line, for example:
static System.Resources.ResourceManager resourceMan = new System.Resources.ResourceManager ("LocalizeDemo.Properties.Resources", typeof (Resources). Assembly);
Implement a file that can be generated containing a list of all resources that you can reference (see Figure 1)
Implement a function to extract and format strings (see Figure 2).
Now you have enough so that you can refer to translated strings from any number of applications (see Figure 3).
Use System.Resources.ResXResourceWriter (from System.Windows.Forms.dll) or System.Resources.ResourceWriter (System.dll) to generate resources instead of the Resx files being your main source. In our project, we have an SQL database that defines all of our lines in each language, and part of our build process generates all the Resx files before creating the resource project.
Now that you can create your Resx files from any format, you can use any format you want (in our case, the SQL database that we export and import from Excel spreadsheets) to provide files for sending to translators.
Also note that translated resources are built as satellite dlls. You could build each language yourself using the right command line tools. If this is part of your question (how to do this) let me know. But at the moment, I assume that you know about this, since the steps of custom assembly have already been mentioned.
Figure 1 is an enumeration identifying all available resources:
namespace MyResources { public enum StrId { Street .... } }
Figure 2 - Code for loading and returning formatted resource strings:
namespace MyResources { public class Resources { static System.Resources.ResourceManager resourceMan = new System.Resources.ResourceManager("MyResources.Properties.Resources", typeof(Resources).Assembly); public static string GetString(StrId name, System.Globalization.CultureInfo culture = null, params string[] substitutions) { if (culture == null) culture = System.Threading.Thread.CurrentThread.CurrentUICulture; string format = resourceMan.GetString(name.ToString(), culture); if (format != null) { return string.Format(format, substitutions); } return name.ToString(); } } }
Figure 3 - Access to resources:
using MyResources; namespace LocalizationDemo { class Program { static void Main(string[] args) { System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("de-DE"); Console.WriteLine(Resources.GetString(StrId.Street)); } } }
source share