Skip to content

Instantly share code, notes, and snippets.

@eocron
Last active October 27, 2017 22:21
Show Gist options
  • Select an option

  • Save eocron/2d9ba79d9f375f74d9e65ad74ea785c9 to your computer and use it in GitHub Desktop.

Select an option

Save eocron/2d9ba79d9f375f74d9e65ad74ea785c9 to your computer and use it in GitHub Desktop.
Easy to user key value wrap around .NET MemoryCache
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