如何在不捕获MissingManifestResourceException

时间:2015-11-26 17:41:32

标签: c# .net resources resourcemanager

我的.resx文件位于我的应用程序的每个客户端的不同命名空间中。说Resources.FirstClient.Home.resxResources.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");
}

有没有更好的方法来了解资源文件是否丢失?

1 个答案:

答案 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 catchGetString快约1000倍。