Skip to content

Commit

Permalink
fix(i18n): load resources where the assembly located at (#3818)
Browse files Browse the repository at this point in the history
  • Loading branch information
ElderJames committed Apr 24, 2024
1 parent 7834205 commit 5a22bb8
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ private string GetResourcePath(Assembly assembly)
private IStringLocalizer GetCachedLocalizer(string resourceName, Assembly assembly, CultureInfo cultureInfo)
{
var cacheKey = GetCacheKey(resourceName, assembly, cultureInfo);
return _cache.GetOrAdd(cacheKey, new SimpleEmbeddedJsonStringLocalizer(resourceName, assembly, cultureInfo, _loggerFactory.CreateLogger<SimpleEmbeddedJsonStringLocalizer>()));
return _cache.GetOrAdd(cacheKey, new SimpleEmbeddedJsonStringLocalizer(resourceName, assembly, cultureInfo, _localizationOptions));
}

private string GetCacheKey(string resourceName, Assembly assembly, CultureInfo cultureInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace AntDesign.Extensions.Localization.EmbeddedJson
{
Expand All @@ -23,12 +24,12 @@ internal class SimpleEmbeddedJsonStringLocalizer : IStringLocalizer
private readonly Lazy<IDictionary<string, string>> _resources;
private readonly Lazy<IDictionary<string, string>> _fallbackResources;

public SimpleEmbeddedJsonStringLocalizer(string resourceName, Assembly resourceAssembly, CultureInfo cultureInfo, ILogger<SimpleEmbeddedJsonStringLocalizer> logger)
public SimpleEmbeddedJsonStringLocalizer(string resourceName, Assembly resourceAssembly, CultureInfo cultureInfo, IOptions<SimpleStringLocalizerOptions> options)
{
_resources = new Lazy<IDictionary<string, string>>(
() => ReadResources(resourceName, resourceAssembly, cultureInfo, logger, isFallback: false));
() => ReadResources(resourceName, resourceAssembly, cultureInfo, options, isFallback: false));
_fallbackResources = new Lazy<IDictionary<string, string>>(
() => ReadResources(resourceName, resourceAssembly, cultureInfo.Parent, logger, isFallback: true));
() => ReadResources(resourceName, resourceAssembly, cultureInfo.Parent, options, isFallback: true));
}

public LocalizedString this[string name]
Expand Down Expand Up @@ -68,32 +69,32 @@ private bool TryGetResource(string name, out string value)
_fallbackResources.Value.TryGetValue(name, out value);
}

private static IDictionary<string, string> ReadResources(string resourcePathName, Assembly resourceAssembly, CultureInfo cultureInfo, ILogger<SimpleEmbeddedJsonStringLocalizer> logger, bool isFallback)
private static IDictionary<string, string> ReadResources(string resourcePathName, Assembly resourceAssembly, CultureInfo cultureInfo, IOptions<SimpleStringLocalizerOptions> options, bool isFallback)
{
var availableResources = resourceAssembly
.GetManifestResourceNames()
.Select(x => Regex.Match(x, $@"^.*{resourcePathName}\.(.+)\.json"))
.Where(x => x.Success)
.Select(x => (CultureName: x.Groups[1].Value, ResourceName: x.Value))
.ToList();
return options.Value.GetResource(cultureInfo.Name) ?? new Dictionary<string, string>();

logger.LogInformation("Available resources:" + string.Join(",", availableResources.Select(x => x.ResourceName).ToArray()));
//var availableResources = resourceAssembly
// .GetManifestResourceNames()
// .Select(x => Regex.Match(x, $@"^.*{resourcePathName}\.(.+)\.json"))
// .Where(x => x.Success)
// .Select(x => (CultureName: x.Groups[1].Value, ResourceName: x.Value))
// .ToList();

var (_, resourceName) = availableResources.FirstOrDefault(x => x.CultureName.Equals(cultureInfo.Name, StringComparison.OrdinalIgnoreCase));
//var (_, resourceName) = availableResources.FirstOrDefault(x => x.CultureName.Equals(cultureInfo.Name, StringComparison.OrdinalIgnoreCase));

if (resourceName == null)
return new Dictionary<string, string>();
//if (resourceName == null)
// return options.Value.GetResource(cultureInfo.Name) ?? new Dictionary<string, string>();

using var stream = resourceAssembly.GetManifestResourceStream(resourceName);
//using var stream = resourceAssembly.GetManifestResourceStream(resourceName);

using var reader = new StreamReader(stream);
//using var reader = new StreamReader(stream);

var json = reader.ReadToEnd();
//var json = reader.ReadToEnd();

return JsonSerializer.Deserialize<IDictionary<string, string>>(json, new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip,
}) ?? throw new InvalidOperationException($"Failed to parse JSON: '{json}'");
//return JsonSerializer.Deserialize<IDictionary<string, string>>(json, new JsonSerializerOptions
//{
// ReadCommentHandling = JsonCommentHandling.Skip,
//}) ?? throw new InvalidOperationException($"Failed to parse JSON: '{json}'");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,59 @@
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Localization;

namespace AntDesign.Extensions.Localization
{
public class SimpleStringLocalizerOptions : LocalizationOptions
{
public Assembly? ResourcesAssembly { get; set; }
private Dictionary<string, IDictionary<string, string>> _cache = new();
private Assembly? _resourcesAssembly;

public IDictionary<string, string>? GetResource(string cultureName)
{
return _cache.TryGetValue(cultureName, out var resource) ? resource : null;
}

public Assembly? ResourcesAssembly
{
get => _resourcesAssembly;
set
{
_resourcesAssembly = value;
if (value != null)
{
LoadResources(value);
}
}
}


private void LoadResources(Assembly resourceAssembly)
{
var availableResources = resourceAssembly
.GetManifestResourceNames()
.Select(x => Regex.Match(x, $@"^.*{ResourcesPath}\.(.+)\.json"))
.Where(x => x.Success)
.ToDictionary(x => x.Groups[1].Value, x => x.Value);

foreach (var resource in availableResources)
{
using var stream = resourceAssembly.GetManifestResourceStream(resource.Value);

using var reader = new StreamReader(stream);

var json = reader.ReadToEnd();

var kv = JsonSerializer.Deserialize<IDictionary<string, string>>(json, new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip,
}) ?? throw new InvalidOperationException($"Failed to parse JSON: '{json}'");

_cache.Add(resource.Key, kv);
}
}
}
}

0 comments on commit 5a22bb8

Please sign in to comment.