Best practices for global resources in c#

When we want to make our application for all users(speak different languages),We need a global technology.
In C# we use ResourceManager as follow:

using System;
using System.Reflection;
using System.Resources;

public class Example
{
   public static void Main()
   {
      // Retrieve the resource.
      ResourceManager rm = new ResourceManager("ExampleResources" , 
                               typeof(Example).Assembly);
      string greeting = rm.GetString("Greeting");

      Console.Write("Enter your name: ");
      string name = Console.ReadLine();
      Console.WriteLine("{0} {1}!", greeting, name);
   }
}
// The example produces output similar to the following:
//       Enter your name: John
//       Hello John!

The assembly have two or more language resources:
Assembly
|--Assembly.en-us.resx
|--Assembly.zh-cn.resx

Then we archive to change the resource by changing thread cultureinfo to use different resource.

If the application have a lot of dll(assembly) files.
I want to have a single point(one resource file for one language) for the application,
Is there a good solution for my idea?

Before I just change the View(eg.Winform or UserControl)'s Language to implement different UI for corresponding language.


Just build the internationalization in C# using the way you described. But as last step of the build process, you can run Fody.Costura.

This will take all the different dlls and pack them into your application so that you only have a single .exe file with everything included.

The benefit is that you can use the C# internationalization frameworks as intended without any hacks, but you still get a single exe you can deliver to your customers.


I find the C# internationalization frameworks very lacking, so I normally make one assembly for resources and reference from the other projects. The resource files I generate from some tool (DB, excel, textfile) and keep both the source data and the resource files under version control.

MyApp.sln
   ResourceProject.csproj   
     Resources.resx
     Resources.ru.resx
     Resources.de.resx
     Resource.cs
   Core.csproj
   UI.csproj

The resource class can load all the different assemblies

 namespace MyApp.Resources
 {
    public static class Resource
    {
       private static ResourceManager manager;
       static Resource()
       {
          manager = new ResourceManager("MyApp.Resources", Assembly.GetAssembly(typeof(Resource)));
       }

       public static string GetString(string key, string culture)
       {
          return GetString(key, new CultureInfo(culture));
       }

       public static string GetString(string key, CultureInfo culture)
       {
          return manager.GetString(key, culture);
       }
    }
 }

This simple class can be extended in various ways. In the calling assemblies you can have utility classes that will call based on the current UI culture or thread culture depending on the situation.

Note that this completely sidesteps any built-in WinForms or WPF i18N methods.

For GUI:s you can make a utility that recursively translates whole forms. The lookup itself can/should be extended with warnings for missing keys, fallback arguments, prefixes/namespaces if you have thousands of keys and so on.

链接地址: http://www.djcxy.com/p/23720.html

上一篇: ASP.NET资源类型错误

下一篇: 全球资源在c#中的最佳实践