I'm hoping this is the correct place to ask this, but after recently experiencing some strange behaviour I realised after doing some research that when using .NET memory cache and you retrieve an object from cache you retrieve a reference to that object in cache, rather than a copy of the object, so any updates to the object will persist in cache.
In the example below the student is updated in the StudentController, and retrieved again the CourseController, with the student containing the updated value without having to refresh the cache.
My initial approach was to clear the cached students collection after updating the DB (because I thought the cached version wouldn't have included the update), but given that this persistence exists is there a need to repopulate the cache again once the database has been updated?
// Student controller
public class StudentController : Controller
{
// omitted for brevity.
public ActionResult UpdateStudent(int id)
{
var student = CollegeCache.Students[id];
student.FirstName = "SpongeBob"
studentRepository.update(student)
// CollegeCache.clearStudents();
}
}
// Course controller
public class CourseController : Controller
{
// omitted for brevity.
public ActionResult GetCoursesDetails(int id)
{
var student = CollegeCache.Students[id];
// here student.FirstName will be "SpongeBob", and not it's original value.
}
}
// Cache helper class
public static class CollegeCache
{
private static readonly ObjectCache cache = new MemoryCache("College");
private static object locker = new object();
public static readonly string StudentsKey = "StudentsKey";
// Clears the entire cache store.
public static void Clear()
{
foreach (var item in cache)
cache.Remove(item.Key);
}
// Clears a single cache entry.
public static void Clear(string key)
{
cache.Remove(key);
}
// Add to cache helper
private static void Add(string key, object value, DateTimeOffset expiration,
CacheItemPriority priority = CacheItemPriority.Default)
{
var policy = new CacheItemPolicy();
policy.AbsoluteExpiration = expiration;
policy.Priority = priority;
var item = new CacheItem(key, value);
cache.Add(item, policy);
}
// Students cache store.
public static Dictionary<int, Student> Students
{
get
{
var dictionary = cache[StudentsKey] as Dictionary<int, Student>;
if (dictionary == null)
{
lock (locker)
{
dictionary = db.Students.All().ToList().ToDictionary(a => a.Id);
Add(StudentsKey, dictionary, DateTime.Now.AddHours(1));
}
}
return dictionary;
}
}
// Clears the users cache store.
public static void ClearStudents()
{
Clear(StudentsKey);
}
}