diff --git a/src/CacheService.csproj b/src/CacheService.csproj index bbef5e8..c4871ac 100644 --- a/src/CacheService.csproj +++ b/src/CacheService.csproj @@ -22,9 +22,9 @@ - - - + + + diff --git a/src/Core/UglyCacheService.cs b/src/Core/UglyCacheService.cs index 2926273..f3610f4 100644 --- a/src/Core/UglyCacheService.cs +++ b/src/Core/UglyCacheService.cs @@ -34,15 +34,19 @@ public UglyCacheService(IOptions configuration, Deleg var result = default(T); AddOrUpdateJob(key, ops, getter); - if (TryGetFromMemory(key, ref result)) - { - return result; - } - result = await TryGetFromDistributedAsync(key, ops, cancellationToken); - if (result is not null) + if (!(options?.ForceRefresh ?? false)) { - return result; + if (TryGetFromMemory(key, ref result)) + { + return result; + } + + result = await TryGetFromDistributedAsync(key, ops, cancellationToken); + if (result is not null) + { + return result; + } } return await TryGetFromSourceAsync(key, getter, ops, cancellationToken); diff --git a/tests/Integration/CacheService_Should.cs b/tests/Integration/CacheService_Should.cs index 71b21dc..831cec4 100644 --- a/tests/Integration/CacheService_Should.cs +++ b/tests/Integration/CacheService_Should.cs @@ -95,7 +95,7 @@ public async Task Write_DistributedCache_When_Value_Is_Too_Big() var distributedValue = DistributedCache[key]; Assert.NotNull(distributedValue); - } + } [Fact] public async Task Delete_MemoryCache_Value_When_It_Is_Invalidated() @@ -117,5 +117,35 @@ public async Task Delete_DistributedCache_Value_When_It_Is_Invalidated() Assert.False(DistributedCache.ContainsKey(key)); } + [Fact] + public async Task Replace_Memory_Value_When_Force_Refresh_Option_Is_Set() + { + var unexpected = new DummyObject(); + MemoryCache.Add(key, new DummyCacheEntry(key) { Value = unexpected }); + + var actual = await Target.GetOrSetAsync(key, new CacheServiceOptions { ForceRefresh = true }, () => expected, CancellationToken); + Assert.Equal(expected, actual); + + var memoryValue = MemoryCache[key].Value; + Assert.Equal(expected, memoryValue); + } + + [Fact] + public async Task Replace_Distributed_Value_When_Force_Refresh_Option_Is_Set() + { + var unexpected = new DummyObject(); + var unexpectedSerialized = System.Text.Encoding.UTF8.GetBytes($@"{{""Id"":""{unexpected.Id}""}}"); + DistributedCache.Add(key, unexpectedSerialized); + + var actual = await Target.GetOrSetAsync(key, new CacheServiceOptions { ForceRefresh = true }, () => expected, CancellationToken); + Assert.Equal(expected, actual); + + // Set operation is async, so we need to wait a bit + await Task.Delay(1000); + + var distributedValue = DistributedCache[key]; + Assert.Equal(serialized, distributedValue); + } + private sealed record TestData(string Id, string Field1, string Field2); } diff --git a/tests/Integration/DistributedChainLink_Serializer_Should.cs b/tests/Integration/DistributedCache_CacheSerializer_Should.cs similarity index 100% rename from tests/Integration/DistributedChainLink_Serializer_Should.cs rename to tests/Integration/DistributedCache_CacheSerializer_Should.cs