如何在不捕获 MissingManifestResourceException 的情况下知道是否找不到资源文件
How to know if a resource file is not found without catching MissingManifestResourceException
我的应用程序的每个客户端都有位于不同命名空间中的 .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");
}
有没有更好的方法知道资源文件是否丢失?
我们最终在应用程序启动时加载了 ResourceManager
的实例,并将它们保存在单例实例中,然后在尝试获取字符串时使用这些实例。
首先,我们将资源管理器加载到字典的字典中,第一个键是客户端名称,第二个键是资源文件的名称(例如: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);
}
根据我们所做的测试,这种方法比在每个 GetString
.
上使用新的 ResourceManager
和 try catch
快大约 1000 倍
我的应用程序的每个客户端都有位于不同命名空间中的 .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");
}
有没有更好的方法知道资源文件是否丢失?
我们最终在应用程序启动时加载了 ResourceManager
的实例,并将它们保存在单例实例中,然后在尝试获取字符串时使用这些实例。
首先,我们将资源管理器加载到字典的字典中,第一个键是客户端名称,第二个键是资源文件的名称(例如: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);
}
根据我们所做的测试,这种方法比在每个 GetString
.
ResourceManager
和 try catch
快大约 1000 倍