Skip to content

Commit 028ca4c

Browse files
committed
refactor: simplified caching
1 parent 9953423 commit 028ca4c

File tree

2 files changed

+8
-38
lines changed

2 files changed

+8
-38
lines changed
Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,30 @@
11
using System;
22
using System.Linq.Expressions;
3-
using System.Threading;
43
using System.Threading.Tasks;
54
using LinkDotNet.Blog.Domain;
65
using Microsoft.Extensions.Caching.Memory;
7-
using Microsoft.Extensions.Primitives;
86

97
namespace LinkDotNet.Blog.Infrastructure.Persistence;
108

11-
public sealed class CachedRepository<T> : IRepository<T>, IDisposable
9+
public sealed class CachedRepository<T> : IRepository<T>
1210
where T : Entity
1311
{
1412
private readonly IRepository<T> repository;
1513
private readonly IMemoryCache memoryCache;
16-
private CancellationTokenSource resetToken = new();
1714

1815
public CachedRepository(IRepository<T> repository, IMemoryCache memoryCache)
1916
{
2017
this.repository = repository;
2118
this.memoryCache = memoryCache;
2219
}
2320

24-
private MemoryCacheEntryOptions Options => new()
25-
{
26-
ExpirationTokens = { new CancellationChangeToken(resetToken.Token) },
27-
AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(7),
28-
};
29-
3021
public async ValueTask<T> GetByIdAsync(string id)
3122
{
32-
if (!memoryCache.TryGetValue(id, out T value))
23+
return await memoryCache.GetOrCreateAsync(id, async entry =>
3324
{
34-
value = await repository.GetByIdAsync(id);
35-
memoryCache.Set(id, value, Options);
36-
}
37-
38-
return value;
25+
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(7);
26+
return await repository.GetByIdAsync(id);
27+
});
3928
}
4029

4130
public async ValueTask<IPagedList<T>> GetAllAsync(
@@ -58,26 +47,12 @@ public async ValueTask<IPagedList<TProjection>> GetAllByProjectionAsync<TProject
5847
public async ValueTask StoreAsync(T entity)
5948
{
6049
await repository.StoreAsync(entity);
61-
ResetCache();
62-
memoryCache.Set(entity.Id, entity, Options);
50+
memoryCache.Remove(entity.Id);
6351
}
6452

6553
public async ValueTask DeleteAsync(string id)
6654
{
67-
ResetCache();
6855
await repository.DeleteAsync(id);
69-
}
70-
71-
public void Dispose() => resetToken?.Dispose();
72-
73-
private void ResetCache()
74-
{
75-
if (resetToken is { IsCancellationRequested: false, Token.CanBeCanceled: true })
76-
{
77-
resetToken.Cancel();
78-
resetToken.Dispose();
79-
}
80-
81-
resetToken = new CancellationTokenSource();
56+
memoryCache.Remove(id);
8257
}
8358
}

tests/LinkDotNet.Blog.UnitTests/Infrastructure/Persistence/CachedRepositoryTests.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace LinkDotNet.Blog.UnitTests.Infrastructure.Persistence;
1111

12-
public sealed class CachedRepositoryTests : IDisposable
12+
public sealed class CachedRepositoryTests
1313
{
1414
private readonly Mock<IRepository<BlogPost>> repositoryMock;
1515
private readonly CachedRepository<BlogPost> sut;
@@ -110,11 +110,6 @@ public async Task ShouldGetFreshDataAfterDelete()
110110
Times.Exactly(2));
111111
}
112112

113-
public void Dispose()
114-
{
115-
sut.Dispose();
116-
}
117-
118113
private void SetupRepository()
119114
{
120115
var blogPost = new BlogPostBuilder().Build();

0 commit comments

Comments
 (0)