1
1
using System ;
2
2
using System . Linq . Expressions ;
3
+ using System . Threading ;
3
4
using System . Threading . Tasks ;
4
5
using LinkDotNet . Blog . Domain ;
5
6
using Microsoft . Extensions . Caching . Memory ;
7
+ using Microsoft . Extensions . Primitives ;
6
8
using X . PagedList ;
7
9
8
10
namespace LinkDotNet . Blog . Infrastructure . Persistence
9
11
{
10
12
public class CachedRepository < T > : IRepository < T >
11
13
where T : Entity
12
14
{
15
+ private static CancellationTokenSource resetToken = new ( ) ;
16
+
13
17
private readonly IRepository < T > repository ;
18
+
14
19
private readonly IMemoryCache memoryCache ;
15
20
16
21
public CachedRepository ( IRepository < T > repository , IMemoryCache memoryCache )
@@ -19,12 +24,18 @@ public CachedRepository(IRepository<T> repository, IMemoryCache memoryCache)
19
24
this . memoryCache = memoryCache ;
20
25
}
21
26
27
+ private static MemoryCacheEntryOptions Options => new ( )
28
+ {
29
+ ExpirationTokens = { new CancellationChangeToken ( resetToken . Token ) } ,
30
+ AbsoluteExpirationRelativeToNow = TimeSpan . FromDays ( 7 ) ,
31
+ } ;
32
+
22
33
public async Task < T > GetByIdAsync ( string id )
23
34
{
24
35
if ( ! memoryCache . TryGetValue ( id , out T value ) )
25
36
{
26
37
value = await repository . GetByIdAsync ( id ) ;
27
- memoryCache . Set ( id , value ) ;
38
+ memoryCache . Set ( id , value , Options ) ;
28
39
}
29
40
30
41
return value ;
@@ -40,24 +51,34 @@ public async Task<IPagedList<T>> GetAllAsync(
40
51
var key = $ "{ filter ? . Body } -{ orderBy ? . Body } -{ descending } -{ page } -{ pageSize } ";
41
52
return await memoryCache . GetOrCreate ( key , async e =>
42
53
{
43
- e . SetOptions ( new MemoryCacheEntryOptions
44
- {
45
- AbsoluteExpirationRelativeToNow = TimeSpan . FromHours ( 1 ) ,
46
- } ) ;
54
+ e . SetOptions ( Options ) ;
47
55
return await repository . GetAllAsync ( filter , orderBy , descending , page , pageSize ) ;
48
56
} ) ;
49
57
}
50
58
51
59
public async Task StoreAsync ( T entity )
52
60
{
53
- memoryCache . Set ( entity . Id , entity , TimeSpan . FromHours ( 1 ) ) ;
61
+ ResetCache ( ) ;
62
+ memoryCache . Set ( entity . Id , entity , Options ) ;
54
63
await repository . StoreAsync ( entity ) ;
55
64
}
56
65
57
66
public async Task DeleteAsync ( string id )
58
67
{
68
+ ResetCache ( ) ;
59
69
memoryCache . Remove ( id ) ;
60
70
await repository . DeleteAsync ( id ) ;
61
71
}
72
+
73
+ private static 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 ( ) ;
82
+ }
62
83
}
63
84
}
0 commit comments