我的.resx文件位于我的应用程序的每个客户端的不同命名空间中。说Resources.FirstClient.Home.resx
和Resources.SecondClient.Home.resx
。大多数字符串对于每个客户端都是通用的,因此我想引入一个默认的命名空间Resources.Default.Home.resx
,如果找不到客户端的字符串,我可以使用它。
我遇到的问题是我不知道如何确定是否找不到资源文件。 (例如Resources.ThirdClient.Home.resx
不存在,所以我想改用"Resources.Default.Home.resx
现在,我发现处理它的唯一方法是捕获MissingManifestResourceException
抛出:
var resourceManager = new ResourceManager("Resources.ThirdClient.Home", typeof(ResourceFactory).Assembly);
string str;
try
{
str = resourceManager.GetString("myString");
}
catch(MissingManifestResourceException e)
{
resourceManager = new ResourceManager("Resources.DefaultClient.Home", typeof(ResourceFactory).Assembly);
str = resourceManager.GetString("myString");
}
有没有更好的方法来了解资源文件是否丢失?
答案 0 :(得分:0)
我们最终在应用程序启动时加载ResourceManager
的实例并将它们保存在Singleton实例中,然后在尝试获取字符串时使用这些实例。
首先,我们将资源管理器加载到字典字典中,第一个键是客户端名称,第二个键是资源文件的名称(例如:resourceManagers["ThirdClient"]["Home"]
)。我们在_tenants列表中也有一个默认值:
var resourceManagers = new Dictionary<string, IDictionary<string, IResourceManagerAdapter>>();
foreach (var tenant in _tenants)
{
var resourceDictionnary = typeof(ResourceFactory)
.Assembly
.GetTypes()
.Where(t => t.IsClass && t.Namespace == "Resources." + tenant)
.ToDictionary<Type, string, ResourceManager>
(resourceFile => resourceFile.Name,
resourceFile => new ResourceManager("Resources." + tenant + "." + resourceFile.Name, typeof(ResourceFactory).Assembly));
resourceManagers.Add(tenant, resourceDictionnary);
}
我们将resourceManagers
字典保存在使用DI容器注入我们服务的单例实例中。
然后我们使用注入的字典来获取字符串,如果找不到则使用默认值:
public string GetString(string classKey, string resourceKey)
{
if (!resourceManagers.ContainsKey(client) || !resourceManagers[client].ContainsKey(classKey))
return resourceManagers[default][classKey].GetString(resourceKey);
return resourceManagers[client][classKey].GetString(resourceKey, _cultureService.GetCurrentCulture())
?? resourceManagers[default][classKey].GetString(resourceKey);
}
从我们所做的测试来看,这种方法比在ResourceManager
上使用新的try catch
和GetString
快约1000倍。