Skip to content

Commit 3be8099

Browse files
(GH-613) Re-factor the in-memory caching provider
1 parent 97277cb commit 3be8099

File tree

3 files changed

+149
-181
lines changed

3 files changed

+149
-181
lines changed

src/DotNetToolkit.Repository.Caching.InMemory/InMemoryCache.cs

Lines changed: 0 additions & 136 deletions
This file was deleted.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
namespace DotNetToolkit.Repository.Caching.InMemory
2+
{
3+
using DotNetToolkit.Repository.Utility;
4+
using JetBrains.Annotations;
5+
using Microsoft.Extensions.Internal;
6+
using System;
7+
8+
/// <summary>
9+
/// The options to be used by the in-memory caching provider.
10+
/// </summary>
11+
public class InMemoryCacheOptions
12+
{
13+
private ISystemClock _clock;
14+
private TimeSpan? _expirationScanFrequency;
15+
private TimeSpan? _expiry;
16+
17+
/// <summary>
18+
/// Gets the system clock.
19+
/// </summary>
20+
public ISystemClock Clock { get { return _clock; } }
21+
22+
/// <summary>
23+
/// Gets the expiration scan frequency.
24+
/// </summary>
25+
public TimeSpan? ExpirationScanFrequency { get { return _expirationScanFrequency; } }
26+
27+
/// <summary>
28+
/// Gets the expiration time.
29+
/// </summary>
30+
public TimeSpan? Expiry { get { return _expiry; } }
31+
32+
/// <summary>
33+
/// Adds the giving system clock vaue to the options.
34+
/// </summary>
35+
/// <param name="clock">The system clock to be added.</param>
36+
public InMemoryCacheOptions WithClock([NotNull] ISystemClock clock)
37+
{
38+
_clock = Guard.NotNull(clock, nameof(clock));
39+
40+
return this;
41+
}
42+
43+
/// <summary>
44+
/// Adds the giving system clock vaue to the options.
45+
/// </summary>
46+
/// <param name="expirationScanFrequency">The minimum length of time between successive scans for expired items to be added.</param>
47+
public InMemoryCacheOptions WithExpirationScanFrequency([NotNull] TimeSpan expirationScanFrequency)
48+
{
49+
_expirationScanFrequency = Guard.NotNull(expirationScanFrequency, nameof(expirationScanFrequency));
50+
51+
return this;
52+
}
53+
54+
/// <summary>
55+
/// Adds the giving caching expiration time to the options.
56+
/// </summary>
57+
/// <param name="expiry">The caching expiration time to be added.</param>
58+
public InMemoryCacheOptions WithExpiry([NotNull] TimeSpan expiry)
59+
{
60+
_expiry = Guard.NotNull(expiry, nameof(expiry));
61+
62+
return this;
63+
}
64+
}
65+
}

src/DotNetToolkit.Repository.Caching.InMemory/InMemoryCacheProvider.cs

Lines changed: 84 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,72 +3,111 @@
33
using Configuration.Caching;
44
using JetBrains.Annotations;
55
using Microsoft.Extensions.Caching.Memory;
6+
using Microsoft.Extensions.Internal;
67
using System;
78
using Utility;
89

9-
/// <summary>
10-
/// An implementation of <see cref="ICacheProvider{TCache}" />.
11-
/// </summary>
12-
public class InMemoryCacheProvider : CacheProviderBase<InMemoryCache>
10+
internal class InMemoryCacheProvider : ICacheProvider
1311
{
12+
#region Properties
13+
14+
public IMemoryCache Cache { get; }
15+
public TimeSpan? Expiry { get; set; }
16+
17+
#endregion
18+
1419
#region Constructors
1520

16-
/// <summary>
17-
/// Initializes a new instance of the <see cref="InMemoryCacheProvider" /> class.
18-
/// </summary>
19-
public InMemoryCacheProvider() : this((TimeSpan?)null) { }
20-
21-
/// <summary>
22-
/// Initializes a new instance of the <see cref="InMemoryCacheProvider" /> class.
23-
/// </summary>
24-
/// <param name="expiry">The caching expiration time.</param>
25-
public InMemoryCacheProvider([CanBeNull] TimeSpan? expiry) : this(new MemoryCache(new MemoryCacheOptions()), expiry) { }
26-
27-
/// <summary>
28-
/// Initializes a new instance of the <see cref="InMemoryCacheProvider" /> class.
29-
/// </summary>
30-
/// <param name="optionsAction">The configuration options action.</param>
31-
public InMemoryCacheProvider([NotNull] Action<MemoryCacheOptions> optionsAction) : this(optionsAction, (TimeSpan?)null) { }
32-
33-
/// <summary>
34-
/// Initializes a new instance of the <see cref="InMemoryCacheProvider" /> class.
35-
/// </summary>
36-
/// <param name="optionsAction">The configuration options action.</param>
37-
/// <param name="expiry">The caching expiration time.</param>
38-
public InMemoryCacheProvider([NotNull] Action<MemoryCacheOptions> optionsAction, [CanBeNull] TimeSpan? expiry) : this(new MemoryCache(GetConfigurationOptions(optionsAction)), expiry) { }
39-
40-
/// <summary>
41-
/// Initializes a new instance of the <see cref="InMemoryCacheProvider" /> class.
42-
/// </summary>
43-
/// <param name="cache">The underlying caching storage.</param>
44-
public InMemoryCacheProvider([NotNull] IMemoryCache cache) : this(cache, (TimeSpan?)null) { }
45-
46-
/// <summary>
47-
/// Initializes a new instance of the <see cref="InMemoryCacheProvider" /> class.
48-
/// </summary>
49-
/// <param name="cache">The underlying caching storage.</param>
50-
/// <param name="expiry">The caching expiration time.</param>
51-
public InMemoryCacheProvider([NotNull] IMemoryCache cache, [CanBeNull] TimeSpan? expiry)
21+
public InMemoryCacheProvider() : this(null, null, null) { }
22+
23+
public InMemoryCacheProvider(ISystemClock clock, TimeSpan? expirationScanFrequency, TimeSpan? expiry)
24+
: this (GetMemoryCacheOptions(clock, expirationScanFrequency), expiry) { }
25+
26+
private InMemoryCacheProvider(MemoryCacheOptions options, TimeSpan? expiry)
5227
{
53-
Cache = new InMemoryCache(Guard.NotNull(cache, nameof(cache)));
28+
Cache = new MemoryCache(Guard.NotNull(options, nameof(options)));
5429
Expiry = expiry;
5530
}
5631

5732
#endregion
5833

5934
#region Private Methods
6035

61-
private static MemoryCacheOptions GetConfigurationOptions(Action<MemoryCacheOptions> optionsAction)
36+
private static MemoryCacheOptions GetMemoryCacheOptions(ISystemClock clock, TimeSpan? expirationScanFrequency)
6237
{
63-
Guard.NotNull(optionsAction, nameof(optionsAction));
64-
6538
var options = new MemoryCacheOptions();
6639

67-
optionsAction(options);
40+
options.Clock = clock;
41+
42+
if (expirationScanFrequency.HasValue)
43+
{
44+
options.ExpirationScanFrequency = expirationScanFrequency.Value;
45+
}
6846

6947
return options;
7048
}
7149

50+
private void Set<T>(string key, T value, CacheItemPriority priority, TimeSpan? expiry, Action<string> cacheRemovedCallback = null)
51+
{
52+
Guard.NotEmpty(key, nameof(key));
53+
54+
var policy = new MemoryCacheEntryOptions();
55+
56+
if (cacheRemovedCallback != null)
57+
{
58+
policy.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration
59+
{
60+
EvictionCallback = (o, val, reason, state) =>
61+
{
62+
cacheRemovedCallback(reason.ToString());
63+
}
64+
});
65+
}
66+
67+
if (expiry.HasValue && expiry.Value != TimeSpan.Zero)
68+
policy.AbsoluteExpiration = DateTimeOffset.Now.Add(expiry.Value);
69+
70+
if (expiry.HasValue && expiry.Value == TimeSpan.Zero && priority != CacheItemPriority.NeverRemove)
71+
policy.Priority = CacheItemPriority.NeverRemove;
72+
else
73+
policy.Priority = priority;
74+
75+
Cache.Set<T>(key, value, policy);
76+
}
77+
78+
#endregion
79+
80+
#region Implementation of ICacheProvider
81+
82+
public void Set<T>([NotNull] string key, T value, TimeSpan? expiry = null, Action<string> cacheRemovedCallback = null)
83+
{
84+
Set<T>(key, value, CacheItemPriority.Normal, expiry ?? Expiry, cacheRemovedCallback);
85+
}
86+
87+
public void Remove([NotNull] string key)
88+
{
89+
Cache.Remove(Guard.NotEmpty(key, nameof(key)));
90+
}
91+
92+
public bool TryGetValue<T>([NotNull] string key, out T value)
93+
{
94+
return Cache.TryGetValue<T>(Guard.NotEmpty(key, nameof(key)), out value);
95+
}
96+
97+
public int Increment([NotNull] string key, int defaultValue, int incrementValue)
98+
{
99+
Guard.NotEmpty(key, nameof(key));
100+
101+
if (!TryGetValue<int>(key, out var current))
102+
current = defaultValue;
103+
104+
var value = current + incrementValue;
105+
106+
Set<int>(key, value, CacheItemPriority.NeverRemove, expiry: null);
107+
108+
return value;
109+
}
110+
72111
#endregion
73112
}
74113
}

0 commit comments

Comments
 (0)