Skip to content

Commit 66a514a

Browse files
authored
fix(Localizer): makes JsonStringLocalizerFactory thread-safe (#7919)
* refactor: 使用 AsyncLocal 数据类型 * test: 补充单元测试 * chore: bump version 10.5.2-beta01 * revert: 撤销版本更新 * test: 补充单元测试 * chore: bump version 10.5.2-beta01 * revert: 撤销版本号更新 * Revert "test: 补充单元测试" This reverts commit 49f36a0.
1 parent bfbafc6 commit 66a514a

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

src/BootstrapBlazor/Localization/Json/JsonStringLocalizerFactory.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Microsoft.Extensions.Localization;
77
using Microsoft.Extensions.Logging;
88
using System.Reflection;
9+
using System.Threading;
910

1011
namespace BootstrapBlazor.Components;
1112

@@ -18,7 +19,7 @@ internal class JsonStringLocalizerFactory : ResourceManagerStringLocalizerFactor
1819
private readonly ILoggerFactory _loggerFactory;
1920
private readonly JsonLocalizationOptions _jsonLocalizationOptions;
2021
private readonly ILocalizationMissingItemHandler _localizationMissingItemHandler;
21-
private string? _typeName;
22+
private readonly AsyncLocal<string?> _typeName = new();
2223

2324
/// <summary>
2425
/// <para lang="zh">构造函数</para>
@@ -81,7 +82,7 @@ protected override string GetResourcePrefix(TypeInfo typeInfo)
8182
var index = typeName.IndexOf('`');
8283
typeName = typeName[..index];
8384
}
84-
_typeName = typeName;
85+
_typeName.Value = typeName;
8586

8687
return base.GetResourcePrefix(typeInfo);
8788
}
@@ -96,7 +97,7 @@ protected override string GetResourcePrefix(string baseResourceName, string base
9697
{
9798
// https://gitee.com/LongbowEnterprise/BootstrapBlazor/issues/I5SRA1
9899
var resourcePrefix = base.GetResourcePrefix(baseResourceName, baseNamespace);
99-
_typeName = $"{baseNamespace}.{baseResourceName}";
100+
_typeName.Value = $"{baseNamespace}.{baseResourceName}";
100101

101102
return resourcePrefix;
102103
}
@@ -108,5 +109,10 @@ protected override string GetResourcePrefix(string baseResourceName, string base
108109
/// </summary>
109110
/// <param name="assembly"><para lang="zh">The assembly to create a <see cref="ResourceManagerStringLocalizer"/> for</para><para lang="en">The assembly to create a <see cref="ResourceManagerStringLocalizer"/> for</para></param>
110111
/// <param name="baseName"><para lang="zh">The base name of the resource to search for</para><para lang="en">The base name of the resource to search for</para></param>
111-
protected override ResourceManagerStringLocalizer CreateResourceManagerStringLocalizer(Assembly assembly, string baseName) => new JsonStringLocalizer(assembly, _typeName!, baseName, _jsonLocalizationOptions, _loggerFactory.CreateLogger<JsonStringLocalizer>(), ResourceNamesCache, _localizationMissingItemHandler);
112+
protected override ResourceManagerStringLocalizer CreateResourceManagerStringLocalizer(Assembly assembly, string baseName)
113+
{
114+
var typeName = _typeName.Value ?? baseName;
115+
_typeName.Value = null;
116+
return new JsonStringLocalizer(assembly, typeName, baseName, _jsonLocalizationOptions, _loggerFactory.CreateLogger<JsonStringLocalizer>(), ResourceNamesCache, _localizationMissingItemHandler);
117+
}
112118
}

test/UnitTest/Localization/JsonStringLocalizerTest.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,20 @@ public void GetResourcePrefix_Ok()
330330
Assert.Equal("test", result.Value);
331331
}
332332

333+
[Fact]
334+
public void CreateResourceManagerStringLocalizer_UseBaseNameWhenTypeNameIsNull()
335+
{
336+
var factory = Context.Services.GetRequiredService<IStringLocalizerFactory>();
337+
var mi = factory.GetType().GetMethod("CreateResourceManagerStringLocalizer", BindingFlags.NonPublic | BindingFlags.Instance)!;
338+
339+
var baseName = typeof(Foo).FullName!;
340+
var localizer = Assert.IsType<IStringLocalizer>(mi.Invoke(factory, [typeof(Foo).Assembly, baseName]), exactMatch: false);
341+
var result = localizer["not-found-key"];
342+
343+
Assert.True(result.ResourceNotFound);
344+
Assert.Equal(baseName, result.SearchedLocation);
345+
}
346+
333347
private static readonly string[] localizationConfigure = ["zh-CN.json"];
334348

335349
[Fact]

0 commit comments

Comments
 (0)