From 576ca219de7c88bba932a6f8b4866e4b4fc88185 Mon Sep 17 00:00:00 2001 From: maliming Date: Sun, 28 Dec 2025 15:01:20 +0800 Subject: [PATCH] Make StaticDefinitionCache thread-safe and add tests --- .../StaticDefinitionCache.cs | 2 +- .../StaticDefinitionCache_Tests.cs | 122 ++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 framework/test/Volo.Abp.Core.Tests/Volo/Abp/StaticDefinitions/StaticDefinitionCache_Tests.cs diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/StaticDefinitions/StaticDefinitionCache.cs b/framework/src/Volo.Abp.Core/Volo/Abp/StaticDefinitions/StaticDefinitionCache.cs index ce9ac7827d..4f6a9bebe4 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/StaticDefinitions/StaticDefinitionCache.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/StaticDefinitions/StaticDefinitionCache.cs @@ -24,7 +24,7 @@ public class StaticDefinitionCache : IStaticDefinitionCache +{ + protected readonly IStaticDefinitionCache> _staticDefinitionCache1; + protected readonly IStaticDefinitionCache> _staticDefinitionCache2; + + public StaticDefinitionCache_Tests() + { + _staticDefinitionCache1 = GetRequiredService>>(); + _staticDefinitionCache2 = GetRequiredService>>(); + } + + [Fact] + public async Task GetOrCreate_Test() + { + var definition1 = new StaticDefinition1 { Name = "Definition1", Value = 1 }; + var definition2 = new StaticDefinition1 { Name = "Definition2", Value = 2 }; + + var definitionsFirstRetrieval = await _staticDefinitionCache1.GetOrCreateAsync(() => + { + return Task.FromResult(new List { definition1, definition2 }); + }); + + var definitionsSecondRetrieval = await _staticDefinitionCache1.GetOrCreateAsync(() => + { + throw new AbpException("Factory should not be called on second retrieval"); + }); + + definitionsFirstRetrieval.ShouldBe(definitionsSecondRetrieval); + + definitionsSecondRetrieval.Count.ShouldBe(2); + + definitionsSecondRetrieval[0].Name.ShouldBe("Definition1"); + definitionsSecondRetrieval[0].Value.ShouldBe(1); + + definitionsSecondRetrieval[1].Name.ShouldBe("Definition2"); + definitionsSecondRetrieval[1].Value.ShouldBe(2); + } + + [Fact] + public async Task Separate_Caches_For_Different_Types_Test() + { + var definitions1 = await _staticDefinitionCache1.GetOrCreateAsync(() => + { + return Task.FromResult(new List { new StaticDefinition1 {Name = "Definition1", Value = 1} }); + }); + var definitions2 = await _staticDefinitionCache2.GetOrCreateAsync(() => + { + return Task.FromResult(new List { new StaticDefinition2 {Name = "DefinitionA", Value = 100} }); + }); + + definitions1.Count.ShouldBe(1); + definitions1[0].Name.ShouldBe("Definition1"); + definitions1[0].Value.ShouldBe(1); + + definitions2.Count.ShouldBe(1); + definitions2[0].Name.ShouldBe("DefinitionA"); + definitions2[0].Value.ShouldBe(100); + } + + [Fact] + public async Task Clear_Test() + { + var definitions1 = await _staticDefinitionCache1.GetOrCreateAsync(() => + { + return Task.FromResult(new List { new StaticDefinition1 {Name = "Definition1", Value = 1} }); + }); + var definitions2 = await _staticDefinitionCache2.GetOrCreateAsync(() => + { + return Task.FromResult(new List { new StaticDefinition2 {Name = "DefinitionA", Value = 100} }); + }); + + definitions1.Count.ShouldBe(1); + definitions1[0].Name.ShouldBe("Definition1"); + definitions1[0].Value.ShouldBe(1); + + definitions2.Count.ShouldBe(1); + definitions2[0].Name.ShouldBe("DefinitionA"); + definitions2[0].Value.ShouldBe(100); + + await _staticDefinitionCache1.ClearAsync(); + await _staticDefinitionCache2.ClearAsync(); + + var definitions1AfterClear = await _staticDefinitionCache1.GetOrCreateAsync(() => + { + return Task.FromResult(new List { new StaticDefinition1 {Name = "DefinitionNew", Value = 10} }); + }); + var definitions2AfterClear = await _staticDefinitionCache2.GetOrCreateAsync(() => + { + return Task.FromResult(new List {new StaticDefinition2 {Name = "DefinitionNewA", Value = 200}}); + }); + + definitions1AfterClear.Count.ShouldBe(1); + definitions1AfterClear[0].Name.ShouldBe("DefinitionNew"); + definitions1AfterClear[0].Value.ShouldBe(10); + + definitions2AfterClear.Count.ShouldBe(1); + definitions2AfterClear[0].Name.ShouldBe("DefinitionNewA"); + definitions2AfterClear[0].Value.ShouldBe(200); + } + + public class StaticDefinition1 + { + public string Name { get; set; } + + public int Value { get; set; } + } + + public class StaticDefinition2 + { + public string Name { get; set; } + + public int Value { get; set; } + } +}