gpt4 book ai didi

.net - 如何本地化来自应用程序中所有线程的字符串资源查找?

转载 作者:行者123 更新时间:2023-12-03 12:57:55 25 4
gpt4 key购买 nike

推荐的最佳实践是设置应用程序线程的当前区域性,以启用资源查找以使用正确的语言。

不幸的是,这并没有为任何其他线程设置文化。这对于线程池线程来说尤其是一个问题。

问题是:如何使用最少的额外管道代码将启用字符串资源查找设置为从线程池线程正确本地化?

编辑:

问题是从字符串表生成的这段代码。

internal static string IDS_MYSTRING {
get {
return ResourceManager.GetString("IDS_MYSTRING", resourceCulture);
}
}

在这种情况下,'resourceCulture' 没有为线程池线程正确设置。我可以调用 'ResourceManager.GetString("IDS_MYSTRING",correctCulture);'但这意味着失去编译时检查字符串是否存在的好处。

我现在想知道修复是否是将字符串表的可见性更改为 public 并设置使用反射枚举的所有程序集的 Culture 属性。

最佳答案

对于将来尝试此操作的任何人,我最终得到了以下代码:

/// <summary>
/// Encapsulates the culture to use for localisation.
/// This class exists so that the culture to use for
/// localisation is defined in one place.
/// Setting the Culture property will change the culture and language
/// used by all assemblies, whether they are loaded before or after
/// the property is changed.
/// </summary>
public class LocalisationCulture
{
private CultureInfo cultureInfo = Thread.CurrentThread.CurrentUICulture;
private static LocalisationCulture instance = new LocalisationCulture();
private List<Assembly> loadedAssemblies = new List<Assembly>();
private static ILog logger = LogManager.GetLogger(typeof(LocalisationCulture));
private object syncRoot = new object();

private LocalisationCulture()
{
AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(this.OnAssemblyLoadEvent);

lock(this.syncRoot)
{
foreach(Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
if(LocalisationCulture.IsAssemblyResourceContaining(assembly))
{
this.loadedAssemblies.Add(assembly);
}
}
}
}

/// <summary>
/// The singleton instance of the LocalisationCulture class.
/// </summary>
public static LocalisationCulture Instance
{
get
{
return LocalisationCulture.instance;
}
}

/// <summary>
/// The culture that all loaded assemblies will use for localisation.
/// Setting the Culture property will change the culture and language
/// used by all assemblies, whether they are loaded before or after
/// the property is changed.
/// </summary>
public CultureInfo Culture
{
get
{
return this.cultureInfo;
}

set
{
// Set the current culture to enable resource look ups to
// use the correct language.

Thread.CurrentThread.CurrentUICulture = value;

// Store the culture info so that it can be retrieved
// elsewhere throughout the applications.

this.cultureInfo = value;

// Set the culture to use for string look ups for all loaded assemblies.

this.SetResourceCultureForAllLoadedAssemblies();
}
}

private static bool IsAssemblyResourceContaining(Assembly assembly)
{
Type[] types = assembly.GetTypes();

foreach(Type t in types)
{
if( t.IsClass
&& t.Name == "Resources")
{
return true;
}
}

return false;
}

private void OnAssemblyLoadEvent(object sender, AssemblyLoadEventArgs args)
{
if(!LocalisationCulture.IsAssemblyResourceContaining(args.LoadedAssembly))
{
return;
}

lock(this.syncRoot)
{
this.loadedAssemblies.Add(args.LoadedAssembly);

this.SetResourceCultureForAssembly(args.LoadedAssembly);
}
}

private void SetResourceCultureForAllLoadedAssemblies()
{
lock(this.syncRoot)
{
foreach(Assembly assembly in this.loadedAssemblies)
{
this.SetResourceCultureForAssembly(assembly);
}
}
}

private void SetResourceCultureForAssembly(Assembly assembly)
{
Type[] types = assembly.GetTypes();

foreach(Type t in types)
{
if( t.IsClass
&& t.Name == "Resources")
{
LocalisationCulture.logger.Debug(String.Format( CultureInfo.InvariantCulture,
"Using culture '{0}' for assembly '{1}'",
this.cultureInfo.EnglishName,
assembly.FullName));

PropertyInfo propertyInfo = t.GetProperty( "Culture",
BindingFlags.GetProperty | BindingFlags.Static | BindingFlags.NonPublic);

MethodInfo methodInfo = propertyInfo.GetSetMethod(true);

methodInfo.Invoke( null,
new object[]{this.cultureInfo} );

break;
}
}
}
}

关于.net - 如何本地化来自应用程序中所有线程的字符串资源查找?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1530506/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com