来自 unix 世界的示例是 gettext,但我敢打赌,您正在寻找更现代的东西。
在它的底部,您必须构建您的字符串消耗代码以使用成员来读取要处理/打印/等的字符串,例如,this.mainForm.Title = StringLib.MainFormTitle
.
StringLib 将只是一个具有大量获取/设置属性的大型静态类。
然后,为您希望支持的每种语言创建单独的程序集,将它们命名为 langpack.en-US.dll、langpack.it-IT.dll 等。每个将包含两个类 - 您将实例化一个类以获取元数据关于语言包(文化、版本等)和另一个类,当被调用时,它会填充您的 StringLib 类的静态属性。
在运行时,查找所有 langpack 文件,然后使用反射加载它们。使用反射找出语言包的名称,将它们显示在列表中供用户选择。用户选择一个语言包,此时您调用语言包中的初始化程序类。初始化器会进行大量调用来初始化 StringLib 类的属性,然后就可以了。
在 MainApp.csproj 中:
public class StringLib {
public static string MainFormTitle { get; set; }
...
}
在 langpack.en-US.csproj 中:
public class LangPackDescriptor : ILangPackDescriptor {
public readonly string LangPackName = "American English";
public readonly string CultureString = "en-US";
...
}
public class EnUsLangPackInit : ILangPackInit {
public void Init() {
StringLib.MainFormTitle = "My Application Name"
...
}
}
在 langpack.it-IT.csproj
public class LangPackDescriptor : ILangPackDescriptor {
public static string LangPackName = "Italian";
public string string CultureString = "it-IT";
...
}
public class ItItLangPackInit : ILangPackInit{
public void Init() {
StringLib.MainFormTitle = "Il Nome Del Mio Applicazione"
...
}
}
使用反射初始化,给定一个文件名:
public void LoadLang(string filename) {
Assembly langpackAssembly;
ILangPackDescriptor descriptor;
ILangPackInit initializer;
langpackAssembly = Assembly.LoadFrom(filename);
Type[] langpackTypes = langpackAssembly.GetExportedTypes();
foreach( Type foundType in langpackTypes ) {
if ( foundType.GetInterfaces().Contains<Type>( typeof(ILangPackDescriptor) ) ) {
descriptor = Activator.CreateInstance(foundType);
}
if ( foundType.GetInterfaces().Contains<Type>( typeof(ILangPackInit) ) ) {
initializer = Activator.CreateInstance(foundType);
}
}
// If the passed-in file was the langpack.en-US.dll file, then this
// calls langpack.en-US.dll's EnUsLangPackInit.Init() method.
initializer.Init();
}