forked from evan-rash/FluentCache
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFluentMemoryCache.cs
145 lines (127 loc) · 4.47 KB
/
FluentMemoryCache.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Caching;
using System.Text;
using System.Threading.Tasks;
namespace FluentCache.RuntimeCaching
{
/// <summary>
/// Provides a FluentCache.ICache wrapper around the System.Runtime.Caching.MemoryCache
/// </summary>
public class FluentMemoryCache : ICache
{
/// <summary>
/// Creates a new FluentMemoryCache wrapper around MemoryCache.Default
/// </summary>
/// <returns></returns>
public static ICache Default()
{
return new FluentMemoryCache(MemoryCache.Default);
}
/// <summary>
/// Creates a new FluentMemoryCache wrapper around the specified MemoryCache
/// </summary>
public FluentMemoryCache(MemoryCache memoryCache)
{
MemoryCache = memoryCache ?? throw new ArgumentNullException("memoryCache");
}
private readonly MemoryCache MemoryCache;
private class Storage
{
public DateTime CacheDate { get; set; }
public DateTime LastValidatedDate { get; set; }
public long Version { get; set; }
public object Value { get; set; }
public CachedValue<T> ToCachedValue<T>()
{
if (!(Value is T))
return null;
return new CachedValue<T>
{
CachedDate = CacheDate,
LastValidatedDate = LastValidatedDate,
Value = (T)Value,
Version = Version
};
}
}
/// <summary>
/// Gets the specified cached value
/// </summary>
public CachedValue<T> Get<T>(string key, string region)
{
string k = GetCacheKey(key, region);
Storage storage = MemoryCache.Get(k) as Storage;
if (storage == null)
return null;
return storage.ToCachedValue<T>();
}
/// <summary>
/// Sets the specified cached value
/// </summary>
public CachedValue<T> Set<T>(string key, string region, T value, CacheExpiration cacheExpiration)
{
DateTime now = DateTime.UtcNow;
string k = GetCacheKey(key, region);
if (MemoryCache.Get(k) is Storage storage)
{
storage.Version++;
storage.LastValidatedDate = now;
storage.CacheDate = now;
storage.Value = value;
}
else
{
storage = new Storage
{
CacheDate = now,
LastValidatedDate = now,
Value = value,
Version = 0L
};
var cachePolicy = new CacheItemPolicy();
if (cacheExpiration.SlidingExpiration != null)
cachePolicy.SlidingExpiration = cacheExpiration.SlidingExpiration.GetValueOrDefault();
MemoryCache.Add(k, storage, cachePolicy);
}
return storage.ToCachedValue<T>();
}
/// <summary>
/// Removes the specified cached value
/// </summary>
public void Remove(string key, string region)
{
string k = GetCacheKey(key, region);
MemoryCache.Remove(k);
}
/// <summary>
/// Marks the specified cached value as modified
/// </summary>
public void MarkAsValidated(string key, string region)
{
DateTime now = DateTime.UtcNow;
string k = GetCacheKey(key, region);
if (MemoryCache.Get(k) is Storage storage)
storage.LastValidatedDate = now;
}
/// <summary>
/// Generates a unique key for the parameter value
/// </summary>
public virtual string GetParameterCacheKeyValue(object parameterValue)
{
return ParameterCacheKeys.GenerateCacheKey(parameterValue);
}
/// <summary>
/// Creates an execution plan for retrieving a cached value
/// </summary>
public virtual Execution.ICacheExecutionPlan<T> CreateExecutionPlan<T>(ICacheStrategy<T> cacheStrategy)
{
return new Execution.CacheExecutionPlan<T>(this, cacheStrategy);
}
private string GetCacheKey(string key, string region)
{
return region + ":" + key;
}
}
}