HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

C# cache controller

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
cachecontrollerstackoverflow

Problem

Problem

Currently my project utilises local caching wherever possible. There is a lot of similar looking code throughout that takes the form:

private static readonly ConcurrentDictionary GetPMLocks = new ConcurrentDictionary();
/// 
/// Retrieve a PM by it's unique ID
/// 
public static PrivateMessage GetPrivateMessage(int messageID)
{
    var cacheIndex = GetPMCacheIndex(messageID);
    var cache = GetCache();
    if (cache[cacheIndex == null])
    {
        try
        {
            GetPMLocks.TryAdd(messageID, new object());
            lock (CacheCommentLocks[messageID])
            {
                if (cache[cacheIndex] == null)
                {
                    using (var db = new DBContext())
                    {
                        var q = CompiledQueries.GetPMByID(db, messageID);
                        var pm = new PrivateMessage(q);

                        cache.Add(cacheIndex, pm, null,
                        Cache.NoAbsoluteExpiration,
                        Cache.NoSlidingExpiration,
                        CacheItemPriority.Normal,
                        null);
                    }
                }
            }
        }
        finally
        {
            object tR;
            GetPMLocks.TryRemove(messageID, out tR);
        }
    }
    return (PrivateMessage) cache[cacheIndex];
}


Solution

I wish to refactor this to be more concise, and to route every cache request through a central controller so it's easy to fix bugs/modify & measure the caching process and performance. So I've created a new LocalCacheController class:

```
public class LocalCacheController
{
private Cache CacheObj_ { get; set; }
private Cache CacheObj {
get
{
if (CacheObj_ == null) CacheObj_ = GetCache();
return CacheObj_;
}
}

///
/// Cache index this cacher is for
///
private string ForCacheIndex { get; }

public LocalCacheController(string cacheIndex, Cache cache

Solution

You have a lots of repetitions there:

private Cache CacheObj_ { get; set; }
private Cache CacheObj
{
  get
  {
      if (CacheObj_ == null) CacheObj_ = GetCache();
      return CacheObj_;
  }
}


and

private static Cache GetCache()
{
  return (HttpContext.Current == null)
          ? HttpRuntime.Cache
          : HttpContext.Current.Cache;
}


This can be all shortend to just:

private Cache Cache => HttpContext.Current?.Cache ?? HttpRuntime.Cache;


public LocalCacheController(string cacheIndex, Cache cacheObj = null)


You don't need to pass the Cache object around. It's actaully static so if you make the Cache propertey static too then you're done.

private satatic Cache Cache => ...


public static void SetIfNotExists(List> items)


As the use of the cache I don't want to know if something already exists or not. I just want to add something to the cache and it should handle the exists/does not exist questions internally.

This should be just AddRange.

private string ForCacheIndex { get; }


This really needs a better name. It's netiher an index nor a for. I suggest something like CacheKey as this looks like one.

public static object GetFromLocalCache(string cacheIndex, Cache cache = null)


As a user I don't really want to know where the object comes from (unless there are more sources and here aren't any other). A simple GetValue or GetObject would be enough. cacheIndex should be key.

Code Snippets

private Cache CacheObj_ { get; set; }
private Cache CacheObj
{
  get
  {
      if (CacheObj_ == null) CacheObj_ = GetCache();
      return CacheObj_;
  }
}
private static Cache GetCache()
{
  return (HttpContext.Current == null)
          ? HttpRuntime.Cache
          : HttpContext.Current.Cache;
}
private Cache Cache => HttpContext.Current?.Cache ?? HttpRuntime.Cache;
public LocalCacheController(string cacheIndex, Cache cacheObj = null)
private satatic Cache Cache => ...

Context

StackExchange Code Review Q#145528, answer score: 2

Revisions (0)

No revisions yet.