I want to realize caching in WCF web service. I'm using the following code:
public interface ICache<T> : IDisposable where T : class
{
string Name { get; }
CacheItemPolicy CacheItemPolicy { get; set; }
long Count { get; }
bool IsDisposed { get; }
void AddOrUpdate(string key, T value);
bool TryGetValue(string key, out T value);
T GetValue(string key);
bool TryRemove(string key, out T value);
void Remove(string key);
bool ContainsKey(string key);
}
public class MemoryCacheWrapper<T> : ICache<T> where T : class
{
private readonly MemoryCache _memoryCache;
private CacheItemPolicy _cacheItemPolicy;
private bool _isDisposed;
public MemoryCacheWrapper(string name, NameValueCollection config = null)
{
_memoryCache = config != null ? new MemoryCache(name, config) : new MemoryCache(name);
_isDisposed = false;
}
public string Name
{
get { return _memoryCache.Name; }
}
public long CacheMemoryLimitInBytes
{
get { return _memoryCache.CacheMemoryLimit; }
}
public long PhysicalMemoryLimit
{
get { return _memoryCache.PhysicalMemoryLimit; }
}
public TimeSpan PollingInterval
{
get { return _memoryCache.PollingInterval; }
}
public CacheItemPolicy CacheItemPolicy
{
get
{
return _cacheItemPolicy;
}
set
{
if (value != null)
{
_cacheItemPolicy = value;
}
}
}
public void AddOrUpdate(string key, T value)
{
_memoryCache.Set(key, value, CacheItemPolicy);
}
public bool TryGetValue(string key, out T value)
{
bool result = false;
value = default(T);
object item = _memoryCache.Get(key);
if (item != null)
{
value = (T)item;
result = true;
}
return result;
}
public T GetValue(string key)
{
return (T)_memoryCache.Get(key);
}
public bool TryRemove(string key, out T value)
{
bool result = false;
value = default(T);
object item = _memoryCache.Remove(key);
if (item != null)
{
result = true;
value = (T)item;
}
return result;
}
public void Remove(string key)
{
_memoryCache.Remove(key);
}
public bool ContainsKey(string key)
{
return _memoryCache.Contains(key);
}
public long Count
{
get { return _memoryCache.GetCount(); }
}
~MemoryCacheWrapper()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!this._isDisposed)
{
if (disposing)
{
_memoryCache.Dispose();
}
}
_isDisposed = true;
}
public bool IsDisposed
{
get { return _isDisposed; }
}
}
This is my service:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class PremieraInteraction : IPremieraInteraction
{
private ICache<InfoLevel> _cacheInfoLevel = new MemoryCacheWrapper<InfoLevel>("MyCache");
public string GetPlacesInfoForSession(int levelId, int clientId, int sessionId)
{
var key = CacheUtils.GenerateKeyForCache(JobName.PlacesInfoForSession.ToString(),clientId, sessionId, levelId);
JavaScriptSerializer serializer = new JavaScriptSerializer();
InfoLevel cachedInfoLevel;
if (_cacheInfoLevel.TryGetValue(key, out cachedInfoLevel))
return serializer.Serialize(new { Success = true, Count = cachedInfoLevel.AllPlacesCount, Free = cachedInfoLevel.FreePlaces });
return serializer.Serialize(new { Success = false, Message = "Some error" });
}
}
What you think about this code?
This is not bad that I create MemoryCacheWrapper
inside service and not static?
Also, MemoryCacheWrapper
are generic. In the future, I need to create several MemoryCacheWrapper
instances:
private ICache<InfoLevel> _cacheInfoLevel = new MemoryCacheWrapper<InfoLevel>("MyCache");
private ICache<OtherObject> _cacheOtherObject= new MemoryCacheWrapper<OtherObject>("MyCache");
Any suggestions are helpful.