.NET MemoryCache Example (original) (raw)

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

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

C#

_cache = new MemoryCache() 

MemoryCache.cs (Add this test class to your Document Service project)

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 Document 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(); } } }