Maris
Maris

Reputation: 4776

Get all translations from all resource files by culture

I have a dynamic amount of resx files. I need to find an elegant way to get all translations from all resource files by culture in the next format:

Dictionary<string, string> (key->$"{resourceName}.${translationKey}", value -> translation value)

I know I can use the next approach:

        ResourceSet resourceSet = MyResource.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
        foreach (DictionaryEntry entry in resourceSet)
        {
            string resourceKey = entry.Key.ToString();
            string resource = entry.Value.ToString();
        }

But it will take all translations from a single resource, but since I have a dynamic amount of resource files it is not too much suitable for me.

Thanks in advance!

Upvotes: 0

Views: 1519

Answers (2)

Maris
Maris

Reputation: 4776

So, I've end up with a next approach:

public Dictionary<string, string> GetAllResources(string culture){
        var result = new Dictionary<string, string>();
        // let's point somehow to our assembly which contains all resource files
        var resourceAssembly = Assembly.GetAssembly(typeof(EnumsResource));
        var resourceTypes = resourceAssembly
            .GetTypes()
            .Where(e => e.Name.EndsWith("Resource"));
        // Culture
        var cultureInfo = new CultureInfo(culture);
        foreach (var resourceType in resourceTypes)
        {
            var resourceManager = (ResourceManager)resourceType.GetProperty("ResourceManager").GetValue(null);
            var resourceName = resourceManager.BaseName.Split('.').Last();
            var resourceSet = resourceManager.GetResourceSet(cultureInfo, true, true);
            foreach (DictionaryEntry entry in resourceSet)
            {
                var resourceKey = $"{resourceName}.{entry.Key}".ToLower();
                var resource = entry.Value.ToString();
                if (!result.ContainsKey(resourceKey))
                {
                    result.Add(resourceKey, resource);
                }
            }
        }

        return result;
}

Keep in mind that it is not the fastest approach, since it uses reflection. So consider using caching strategy.

Upvotes: 0

Thomas Eggemann
Thomas Eggemann

Reputation: 86

This worked for me:

var resourceManager = Properties.Resources.ResourceManager;
var resourceSets = new Dictionary<CultureInfo,ResourceSet>();
CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
foreach (var ci in cultures)
{
    var resourceSet = resourceManager.GetResourceSet(ci, true, false);
    if (resourceSet != null)
        resourceSets.Add(ci, resourceSet);
}

I have two resource files in the solution Resources.resx and Resources.de-DE.resx. The dictionary will contain the available cultureinfos as the key with the corresponding ResourceSetobjects as value. The first ResourceSet has ? CultureInfo.InvariantCulture (just another name for en-US) as the key.

Upvotes: 1

Related Questions