Skip to content

Commit 96dea7c

Browse files
committed
fix
1 parent f9ca554 commit 96dea7c

File tree

5 files changed

+44
-17
lines changed

5 files changed

+44
-17
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Linq;
2+
using System.Reflection;
3+
using System.Threading;
4+
5+
namespace Eocron.DependencyInjection.Interceptors.Caching
6+
{
7+
public static class KeyProviderHelper
8+
{
9+
public static object AllExceptCancellationToken(MethodInfo methodInfo, object[] args)
10+
{
11+
return new CompoundKey(args.Where(x => x is not CancellationToken).ToList());
12+
}
13+
}
14+
}

Eocron.DependencyInjection.Interceptors/Caching/MemoryCacheAsyncInterceptor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34
using System.Reflection;
5+
using System.Threading;
46
using System.Threading.Tasks;
57
using Castle.DynamicProxy;
68
using Microsoft.Extensions.Caching.Memory;

Eocron.DependencyInjection.Interceptors/DecoratorChainExtensions.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,36 +112,36 @@ public static DecoratorChain AddExponentialBackoff(this DecoratorChain decorator
112112
}
113113

114114
public static DecoratorChain AddCache(this DecoratorChain decoratorChain,
115-
Func<MethodInfo, object[], object> keyProvider)
115+
Func<MethodInfo, object[], object> keyProvider = null)
116116
{
117117
decoratorChain.AddInterceptor(sp => new MemoryCacheAsyncInterceptor(sp.GetRequiredService<IMemoryCache>(),
118-
keyProvider,
118+
keyProvider ?? KeyProviderHelper.AllExceptCancellationToken,
119119
(_,_,_)=> {}));
120120
return decoratorChain;
121121
}
122122

123123
public static DecoratorChain AddSlidingTimeoutCache(this DecoratorChain decoratorChain,
124124
TimeSpan cacheDuration,
125-
Func<MethodInfo, object[], object> keyProvider)
125+
Func<MethodInfo, object[], object> keyProvider = null)
126126
{
127127
if (cacheDuration <= TimeSpan.Zero)
128128
return decoratorChain;
129129

130130
decoratorChain.AddInterceptor(sp => new MemoryCacheAsyncInterceptor(sp.GetRequiredService<IMemoryCache>(),
131-
keyProvider,
131+
keyProvider ?? KeyProviderHelper.AllExceptCancellationToken,
132132
(_,_,ce)=> ce.SetSlidingExpiration(cacheDuration)));
133133
return decoratorChain;
134134
}
135135

136136
public static DecoratorChain AddAbsoluteTimeoutCache(this DecoratorChain decoratorChain,
137137
TimeSpan cacheDuration,
138-
Func<MethodInfo, object[], object> keyProvider)
138+
Func<MethodInfo, object[], object> keyProvider = null)
139139
{
140140
if (cacheDuration <= TimeSpan.Zero)
141141
return decoratorChain;
142142

143143
decoratorChain.AddInterceptor(sp => new MemoryCacheAsyncInterceptor(sp.GetRequiredService<IMemoryCache>(),
144-
keyProvider,
144+
keyProvider ?? KeyProviderHelper.AllExceptCancellationToken,
145145
(_,_,ce)=> ce.SetAbsoluteExpiration(cacheDuration)));
146146
return decoratorChain;
147147
}

Eocron.DependencyInjection.Tests/DependencyInjectionTests/CacheTests.cs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,27 @@ namespace Eocron.DependencyInjection.Tests.DependencyInjectionTests
1010
{
1111
public class CacheTests : BaseDependencyInjectionTests
1212
{
13+
[Test]
14+
public async Task ConstantCache()
15+
{
16+
Instance.Setup(x => x.WorkWithResultAsync(It.Is<int>(i=> i==1), It.IsAny<CancellationToken>())).ReturnsAsync(1);
17+
Instance.Setup(x => x.WorkWithResultAsync(It.Is<int>(i=> i==2), It.IsAny<CancellationToken>())).ReturnsAsync(2);
18+
19+
var proxy = CreateTestObject(x => x.AddAbsoluteTimeoutCache(Expiration));
20+
await Parallel.ForAsync(0, 100, async (_, _) =>
21+
{
22+
(await proxy.WorkWithResultAsync(1, Ct)).Should().Be(1);
23+
});
24+
Instance.Verify(x=> x.WorkWithResultAsync(It.IsAny<int>(), It.IsAny<CancellationToken>()), Times.Exactly(1));
25+
}
26+
1327
[Test]
1428
public async Task AbsoluteExpirationErrorNotCached()
1529
{
1630
Instance.Setup(x => x.WorkWithResultAsync(It.IsAny<int>(), It.IsAny<CancellationToken>()))
1731
.ThrowsAsync(new InvalidOperationException());
1832

19-
var proxy = CreateTestObject(x => x.AddAbsoluteTimeoutCache(Expiration, (method, args) => args[0]));
33+
var proxy = CreateTestObject(x => x.AddAbsoluteTimeoutCache(Expiration));
2034

2135
var func = async () => await proxy.WorkWithResultAsync(1, Ct);
2236
await func.Should().ThrowAsync<InvalidOperationException>();
@@ -31,7 +45,7 @@ public async Task SlidingExpirationErrorNotCached()
3145
Instance.Setup(x => x.WorkWithResultAsync(It.IsAny<int>(), It.IsAny<CancellationToken>()))
3246
.ThrowsAsync(new InvalidOperationException());
3347

34-
var proxy = CreateTestObject(x => x.AddSlidingTimeoutCache(Expiration, (method, args) => args[0]));
48+
var proxy = CreateTestObject(x => x.AddSlidingTimeoutCache(Expiration));
3549

3650
var func = async () => await proxy.WorkWithResultAsync(1, Ct);
3751
await func.Should().ThrowAsync<InvalidOperationException>();
@@ -46,7 +60,7 @@ public async Task AbsoluteExpiration()
4660
Instance.Setup(x => x.WorkWithResultAsync(It.Is<int>(i=> i==1), It.IsAny<CancellationToken>())).ReturnsAsync(1);
4761
Instance.Setup(x => x.WorkWithResultAsync(It.Is<int>(i=> i==2), It.IsAny<CancellationToken>())).ReturnsAsync(2);
4862

49-
var proxy = CreateTestObject(x => x.AddAbsoluteTimeoutCache(Expiration, (method, args) => args[0]));
63+
var proxy = CreateTestObject(x => x.AddAbsoluteTimeoutCache(Expiration));
5064

5165
//first pass
5266
await Parallel.ForAsync(0, 100, async (_, _) =>
@@ -73,7 +87,7 @@ public async Task SlidingExpiration()
7387
Instance.Setup(x => x.WorkWithResultAsync(It.Is<int>(i=> i==1), It.IsAny<CancellationToken>())).ReturnsAsync(1);
7488
Instance.Setup(x => x.WorkWithResultAsync(It.Is<int>(i=> i==2), It.IsAny<CancellationToken>())).ReturnsAsync(2);
7589

76-
var proxy = CreateTestObject(x => x.AddSlidingTimeoutCache(Expiration, (method, args) => args[0]));
90+
var proxy = CreateTestObject(x => x.AddSlidingTimeoutCache(Expiration));
7791

7892
//first pass
7993
await Parallel.ForAsync(0, 100, async (_, _) =>
@@ -100,7 +114,7 @@ public async Task SlidingExpirationOverlap()
100114
Instance.Setup(x => x.WorkWithResultAsync(It.Is<int>(i=> i==1), It.IsAny<CancellationToken>())).ReturnsAsync(1);
101115
Instance.Setup(x => x.WorkWithResultAsync(It.Is<int>(i=> i==2), It.IsAny<CancellationToken>())).ReturnsAsync(2);
102116

103-
var proxy = CreateTestObject(x => x.AddSlidingTimeoutCache(Expiration, (method, args) => args[0]));
117+
var proxy = CreateTestObject(x => x.AddSlidingTimeoutCache(Expiration));
104118

105119
//first pass
106120
await Parallel.ForAsync(0, 100, async (_, _) =>

Eocron.DependencyInjection.Tests/MemoryCacheInterceptorTests.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,14 @@ public async Task CachingAndKeySharing()
4242

4343
var r1 = await proxy.WorkWithResultAsync(2, token);
4444
var r2 = await proxy.WorkWithResultAsync(2, token);
45-
4645
r1.Should().Be(r2);
47-
48-
instance.Verify(x => x.WorkWithResultAsync(It.IsAny<int>(), It.IsAny<CancellationToken>()),
49-
Times.Exactly(1));
50-
5146
r1 = proxy.WorkWithResult(2);
5247
r2 = proxy.WorkWithResult(2);
53-
5448
r1.Should().Be(r2);
49+
5550
instance.Verify(x => x.WorkWithResult(It.IsAny<int>()), Times.Exactly(1));
51+
instance.Verify(x => x.WorkWithResultAsync(It.IsAny<int>(), It.IsAny<CancellationToken>()),
52+
Times.Exactly(1));
5653
}
5754

5855
[Test]

0 commit comments

Comments
 (0)