Last active
October 27, 2017 22:21
-
-
Save eocron/2d9ba79d9f375f74d9e65ad74ea785c9 to your computer and use it in GitHub Desktop.
Easy to user key value wrap around .NET MemoryCache
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Runtime.Caching; | |
| namespace Helpers | |
| { | |
| public interface IObjectCache<in TKey, TValue> | |
| { | |
| bool AddOrUpdateSlide(TKey key, TValue value, TimeSpan expiration); | |
| TValue GetOrAddSlide(TKey key, TimeSpan expiration); | |
| bool AddOrUpdateAbsolute(TKey key, TValue value, DateTime expiration); | |
| TValue GetOrAddAbsolute(TKey key, DateTime expiration); | |
| bool TryGet(TKey key, out TValue value); | |
| } | |
| public class ObjectCache<TKey, TValue> : IObjectCache<TKey, TValue> | |
| { | |
| private sealed class CachedObject | |
| { | |
| public TValue Value { get; set; } | |
| } | |
| private readonly Func<TKey, TValue> _valueProvider; | |
| private readonly string _cacheId; | |
| private readonly MemoryCache _cache; | |
| private readonly object _sync; | |
| public ObjectCache(Func<TKey, TValue> valueProvider) | |
| { | |
| _valueProvider = valueProvider; | |
| _cacheId = Guid.NewGuid().ToString("N"); | |
| _cache = MemoryCache.Default; | |
| _sync = new object(); | |
| } | |
| private string GetCacheKey(TKey key) | |
| { | |
| return _cacheId + key; | |
| } | |
| public bool AddOrUpdateSlide(TKey key, TValue value, TimeSpan expiration) | |
| { | |
| return InternalAddOrUpdate(key, | |
| value, | |
| new CacheItemPolicy | |
| { | |
| SlidingExpiration = expiration | |
| }); | |
| } | |
| private bool InternalAddOrUpdate(TKey key, TValue value, CacheItemPolicy policy) | |
| { | |
| var cacheKey = GetCacheKey(key); | |
| lock (_sync) | |
| { | |
| return _cache.Add(cacheKey, | |
| new CachedObject | |
| { | |
| Value = value | |
| }, | |
| policy); | |
| } | |
| } | |
| public TValue GetOrAddSlide(TKey key, TimeSpan expiration) | |
| { | |
| return InternalGetOrAdd(key, | |
| new CacheItemPolicy | |
| { | |
| SlidingExpiration = expiration | |
| }); | |
| } | |
| private TValue InternalGetOrAdd(TKey key, CacheItemPolicy policy) | |
| { | |
| var cacheKey = GetCacheKey(key); | |
| var obj = _cache.Get(cacheKey) as CachedObject; | |
| if (obj != null) | |
| { | |
| return obj.Value; | |
| } | |
| lock (_sync) | |
| { | |
| obj = _cache.Get(cacheKey) as CachedObject; | |
| if (obj != null) | |
| { | |
| return obj.Value; | |
| } | |
| obj = new CachedObject | |
| { | |
| Value = _valueProvider(key) | |
| }; | |
| _cache.Add(cacheKey, obj, policy); | |
| return obj.Value; | |
| } | |
| } | |
| public bool TryGet(TKey key, out TValue value) | |
| { | |
| value = default(TValue); | |
| var cacheKey = GetCacheKey(key); | |
| var obj = _cache.Get(cacheKey) as CachedObject; | |
| if (obj != null) | |
| { | |
| value = obj.Value; | |
| return true; | |
| } | |
| return false; | |
| } | |
| public bool AddOrUpdateAbsolute(TKey key, TValue value, DateTime expiration) | |
| { | |
| return InternalAddOrUpdate(key, | |
| value, | |
| new CacheItemPolicy | |
| { | |
| AbsoluteExpiration = expiration | |
| }); | |
| } | |
| public TValue GetOrAddAbsolute(TKey key, DateTime expiration) | |
| { | |
| return InternalGetOrAdd(key, | |
| new CacheItemPolicy | |
| { | |
| AbsoluteExpiration = expiration | |
| }); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment