.NET MemoryCache Example

This example shows a simple in-memory cache implementation showing the basics of custom caching and should not be used in a production environment.

In the Documents Service source code, replace the code inside ServiceHelper.CreateCache with:

_cache = new MemoryCache()

MemoryCache.cs

C#
using Leadtools.Caching; 
 
using System; 
using System.Collections.Concurrent; 
using System.Collections.Generic; 
 
namespace MyNamespace 
{ 
   public class MemoryCache : ObjectCache 
   { 
      // The cache. A concurrent dictionary of string|object 
      private ConcurrentDictionary<string, object> _cache = new ConcurrentDictionary<string, object>(); 
 
      // 
      // These members must be implemented by our class and are called by the Documents toolkit 
      // 
 
      // Our name 
      public override string Name 
      { 
         get 
         { 
            return "Memory Cache"; 
         } 
      } 
 
      // We only support binary serialization. In reality, we do not support policies nor serialization, but we return Binary 
      // to inform any callers to not bother sending us any JSON data 
      public override CacheSerializationMode PolicySerializationMode 
      { 
         get 
         { 
            return CacheSerializationMode.Binary; 
         } 
 
         set 
         { 
            throw new NotSupportedException(); 
         } 
      } 
 
      public override CacheSerializationMode DataSerializationMode 
      { 
         get 
         { 
            return CacheSerializationMode.Binary; 
         } 
 
         set 
         { 
            throw new NotSupportedException(); 
         } 
      } 
 
      // We have no special extra support 
      public override DefaultCacheCapabilities DefaultCacheCapabilities 
      { 
         get 
         { 
            return DefaultCacheCapabilities.None; 
         } 
      } 
 
      public override CacheItem<T> AddOrGetExisting<T>(CacheItem<T> item, CacheItemPolicy policy) 
      { 
         if (item == null) 
            throw new ArgumentNullException("item"); 
 
         // Resolve the key, remember, we do not have regions 
         var resolvedKey = ResolveKey(item.RegionName, item.Key); 
 
         CacheItem<T> oldItem = null; 
 
         // Try to get the old value 
         // Yes, save the old value to return it to the user 
         object oldPayload; 
         if (_cache.TryGetValue(resolvedKey, out oldPayload)) 
            oldItem = new CacheItem<T>(item.Key, (T)oldPayload, item.RegionName); 
 
         // Set the new data 
         _cache.TryAdd(resolvedKey, item.Value); 
 
         // Return old item 
         return oldItem; 
      } 
 
      public override CacheItem<T> GetCacheItem<T>(string key, string regionName) 
      { 
         // If we have an item with this key, return it. Otherwise return null 
 
         var resolvedKey = ResolveKey(regionName, key); 
 
         CacheItem<T> item = null; 
 
         object payload; 
         if (_cache.TryGetValue(resolvedKey, out payload)) 
            item = new CacheItem<T>(key, (T)payload, regionName); 
 
         return item; 
      } 
 
      public override bool Contains(string key, string regionName) 
      { 
         // Check if the key is in the dictionary 
 
         var resolvedKey = ResolveKey(regionName, key); 
         var exists = _cache.ContainsKey(resolvedKey); 
 
         return exists; 
      } 
 
      public override bool UpdateCacheItem<T>(CacheItem<T> item) 
      { 
         // Update the item  
 
         if (item == null) 
            throw new ArgumentNullException("item"); 
 
         var resolvedKey = ResolveKey(item.RegionName, item.Key); 
         var exists = _cache.ContainsKey(resolvedKey); 
         if (exists) 
            _cache[resolvedKey] = item.Value; 
 
         return exists; 
      } 
 
      public override T Remove<T>(string key, string regionName) 
      { 
         // Removed if exists, return old value 
 
         var resolvedKey = ResolveKey(regionName, key); 
 
         object payload; 
         var removed = _cache.TryRemove(resolvedKey, out payload); 
         return removed ? (T)payload : default(T); 
      } 
 
      public override void DeleteItem(string key, string regionName) 
      { 
         // Remove if exists 
 
         var resolvedKey = ResolveKey(regionName, key); 
         object payload; 
         _cache.TryRemove(resolvedKey, out payload); 
      } 
 
      private static string ResolveKey(string regionName, string key) 
      { 
         // Both must me non-empty strings 
         if (string.IsNullOrEmpty(regionName)) throw new InvalidOperationException("Region name must be a none empty string"); 
         if (string.IsNullOrEmpty(key)) throw new InvalidOperationException("Region key name must be a none empty string"); 
 
         // We are a simple dictionary with no grouping. regionName might not be unique, key might not be unique, but combine them 
         // and we are guaranteed a unique key 
         return regionName + "-" + key; 
      } 
 
      public override void UpdatePolicy(string key, CacheItemPolicy policy, string regionName) 
      { 
         // Nothing to do 
      } 
 
      // 
      // These members must be over implemented by our class but are never called by the Documents toolkit 
      // So just throw a not supported exception 
      // 
 
      // This is for default region support. We do not have that 
      public override object this[string key] 
      { 
         get 
         { 
            throw new NotSupportedException(); 
         } 
         set 
         { 
            throw new NotSupportedException(); 
         } 
      } 
 
      // Delete a region in one shot. We do not support that 
      // Note: This is only called if we have DefaultCacheCapabilities.CacheRegions. Since we do not, the caller is responsible for 
      // calling DeleteAll passing all the items of the region (which in turn will call DeleteItem for each) 
      public override void DeleteRegion(string regionName) 
      { 
         throw new NotSupportedException(); 
      } 
 
      // Begin adding an external resource. We do not support that 
      // Note: This is only called if we have DefaultCacheCapabilities.ExternalResources 
      public override Uri BeginAddExternalResource(string key, string regionName, bool readWrite) 
      { 
         throw new NotSupportedException(); 
      } 
 
      // End adding an external resource. We do not support that 
      // Note: This is only called if we have DefaultCacheCapabilities.ExternalResources 
      public override void EndAddExternalResource<T>(bool commit, string key, T value, CacheItemPolicy policy, string regionName) 
      { 
         throw new NotSupportedException(); 
      } 
 
      // Get the item external resource. We do not support that 
      // Note: This is only called if we have DefaultCacheCapabilities.ExternalResources 
      public override Uri GetItemExternalResource(string key, string regionName, bool readWrite) 
      { 
         throw new NotSupportedException(); 
      } 
 
      // Remove the item external resource. We do not support that 
      // Note: This is only called if we have DefaultCacheCapabilities.ExternalResources 
      public override void RemoveItemExternalResource(string key, string regionName) 
      { 
         throw new NotSupportedException(); 
      } 
 
      // Get the item virtual directory path. We do not support that 
      // Note: This is only called if we have DefaultCacheCapabilities.VirtualDirectory 
      public override Uri GetItemVirtualDirectoryUrl(string key, string regionName) 
      { 
         throw new NotSupportedException(); 
      } 
 
      // Getting number of items in the cache. We do not support that 
      public override long GetCount(string regionName) 
      { 
         throw new NotSupportedException(); 
      } 
 
      // Statistics. We do not support that 
      public override CacheStatistics GetStatistics() 
      { 
         throw new NotSupportedException(); 
      } 
 
      // Statistics. We do not support that 
      public override CacheStatistics GetStatistics(string key, string regionName) 
      { 
         throw new NotSupportedException(); 
      } 
 
      // Getting all the values. We do not support that 
      public override IDictionary<string, object> GetValues(IEnumerable<string> keys, string regionName) 
      { 
         throw new NotSupportedException(); 
      } 
 
      // Enumeration of the items. We do not support that 
      protected override IEnumerator<KeyValuePair<string, object>> GetEnumerator() 
      { 
         throw new NotSupportedException(); 
      } 
 
 
      // Enumeration of the keys. We do not support that 
      public override void EnumerateKeys(string region, EnumerateCacheEntriesCallback callback) 
      { 
         throw new NotSupportedException(); 
      } 
 
      // Enumeration of regions. We do not support that 
      public override void EnumerateRegions(EnumerateCacheEntriesCallback callback) 
      { 
         throw new NotSupportedException(); 
      } 
   } 
} 

Products | Support | Contact Us | Copyright Notices
© 1991-2017 LEAD Technologies, Inc. All Rights Reserved.
LEADTOOLS HTML5 JavaScript
Click or drag to resize