Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use Microsoft.Extensions.Caching.Memory for object caching in .net core #3226

Closed
KamranShahid opened this issue May 5, 2020 · 5 comments

Comments

@KamranShahid
Copy link

KamranShahid commented May 5, 2020

I were system.runtime.caching for object caching. i have heard that it is recommended to use Microsoft.Extensions.Caching.Memory for caching in .net core 3.1

I am not able to create object of memorycache .
My logic for Caching in System.Runtime caching is as following .
Please help me implementing similar object caching with Microsoft.Extensions.Caching.Memory

    public static class MemoryCacheManager
    {
        private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        public static bool EnableCache = false;   
        public static void Add<T>(string key, T o)
        {
            try
            {
                if (o != null)//https://github.com/mikeedwards83/Glass.Mapper/issues/283
                {
                    if (CacheEnable())
                    {
                        if (!Exists(key))
                        {

                            ObjectCache defCache = MemoryCache.Default;
                            defCache.Add(key, o, new CacheItemPolicy { Priority = CacheItemPriority.Default });
                            Logger.DebugFormat("Key : {0} inserted", key);

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Fatal($"key:{key},exception:{ex.Message}");
            }
        }

        private static bool CacheEnable()
        {
            return EnableCache;
        }

        /// <summary>
        /// Remove item from cache
        /// </summary>
        /// <param name="key">Name of cached item</param>

        public static bool Clear(string key)
        {
            var keyDeleted = false;
            if (CacheEnable())
            {
                try
                {
                    if (Exists(key))
                    {
                        ObjectCache defCache = MemoryCache.Default;
                        defCache.Remove(key);

                        Logger.InfoFormat("Key : {0} cleared", key);
                        keyDeleted = true;
                    }
                    else
                        Logger.InfoFormat("key : {0} not found", key);
                }
                catch (Exception ex)
                {
                    Logger.Fatal($"key:{key},exception:{ex.Message}");
                }
            }
            return keyDeleted;
        }

        public static bool Exists(string key)
        {
            ObjectCache defCache = MemoryCache.Default;
            return defCache[key] != null;
        }



        public static T Get<T>(string key)
        {
            try
            {
                if (CacheEnable())
                {
                    if (Exists(key))
                    {
                        ObjectCache defCache = MemoryCache.Default;
                        return (T)defCache[key];
                    }
                    Logger.DebugFormat("Key : {0} does not exists", key);
                }
                return default;
            }
            catch (Exception ex)
            {
                Logger.Fatal($"key:{key},exception:{ex.Message}");
                return default;
            }
        }



        public static bool ClearFromTablePrefix(string key)
        {
            var keyDeleted = false;
            if (CacheEnable())
            {
                var cacheKeys = MemoryCache.Default.Select(kvp => kvp.Key).ToList();
                var cacheItem = new List<string>();
                foreach (var cacheKey in cacheKeys)
                {
                    if (cacheKey.StartsWith(key))
                        cacheItem.Add(cacheKey);
                }               
                Logger.DebugFormat("Number of Key(s) found {0}, with Prefix {1}", cacheItem.Count, key);               
                try
                {
                    foreach (var newkey in cacheItem)
                    {
                        ObjectCache defCache = MemoryCache.Default;
                        defCache.Remove(key);
                        //if (LogCacheRelatedActivities)
                        {
                            Logger.DebugFormat("Key : {0} cleared", newkey);
                        }
                    }
                    keyDeleted = true;
                }
                catch (Exception ex)
                {
                    Logger.Fatal($"key:{key},exception:{ex.Message}");
                }

            }
            return keyDeleted;
        }



        public static bool RemoveAllCache()
        {
            try
            {
                if (CacheEnable())
                {
                    var cacheKeys = MemoryCache.Default.Select(kvp => kvp.Key).ToList();
                    foreach (var cacheKey in cacheKeys)
                    {
                        MemoryCache.Default.Remove(cacheKey);
                    }                   
                }
                return true;
            }
            catch (Exception ex)
            {
                Logger.Fatal(ex.Message);
                return false;
            }
        }       
    }


@Pilchie
Copy link
Member

Pilchie commented May 5, 2020

Take a look at the docs for a good starting point. This repo doesn't exist to implement things for you, but if you run into specific problems that you don't know how to solve, we might be able to provide pointers to them.

@KamranShahid
Copy link
Author

Take a look at the docs for a good starting point. This repo doesn't exist to implement things for you, but if you run into specific problems that you don't know how to solve, we might be able to provide pointers to them.

Thanks

I think following will be the starting point for me
public class MyMemoryCache
{
public MemoryCache Cache { get; set; }
public MyMemoryCache()
{
Cache = new MemoryCache(new MemoryCacheOptions()
);
}
}
will step by step try to convert my implementation to this

@KamranShahid
Copy link
Author

Take a look at the docs for a good starting point. This repo doesn't exist to implement things for you, but if you run into specific problems that you don't know how to solve, we might be able to provide pointers to them.

Able to convert all previous implementation of System.Runtime caching to this Microsoft.Extensions.Caching.Memory.
One problem i had about list of keys being used currently but it wasn't there in this package. So used a workaround regarding it.

@KamranShahid
Copy link
Author

KamranShahid commented May 6, 2020

My implementation is as following. Adding it here as it might help other's. if there is any improvement suggested then please let me know

    public static class MemoryCacheManager
    {
        private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        public static bool EnableCache = false;
        public static MemoryCache Cache { get; set; }
        static MemoryCacheManager()
        {            
            Cache = new MemoryCache(new MemoryCacheOptions());
        }
        public static void Add<T>(string key, T o)
        {
            try
            {
                if (CacheEnable())
                {
                    if (!Exists(key))
                    {
                        //var cacheEntryOptions = new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromHours(24));
                        Cache.Set(key, o);
                        Logger.DebugFormat("Key : {0} inserted", key);

                    }                   
                }

            }
            catch (Exception ex)
            {
                Logger.Fatal($"key:{key},exception:{ex.Message}");
            }
        }

        private static List<string> GetAllKeysList()
        {
            var field = typeof(MemoryCache).GetProperty("EntriesCollection", BindingFlags.NonPublic | BindingFlags.Instance);
            var collection = field.GetValue(Cache) as ICollection;
            var items = new List<string>();
            if (collection != null)
                foreach (var item in collection)
                {
                    var methodInfo = item.GetType().GetProperty("Key");
                    var val = methodInfo.GetValue(item);
                    items.Add(val.ToString());
                }
            return items;
        }


        private static bool CacheEnable()
        {
            return EnableCache;
        }

        public static bool Clear(string key)
        {
            var keyDeleted = false;
            if (CacheEnable())
            {
                try
                {
                    if (Exists(key))
                    {
                        Cache.Remove(key);
                        Logger.InfoFormat("Key : {0} cleared", key);
                        keyDeleted = true;
                    }
                    else
                        Logger.InfoFormat("key : {0} not found", key);
                }
                catch (Exception ex)
                {
                    Logger.Fatal($"key:{key},exception:{ex.Message}");
                }
            }
            return keyDeleted;
        }

        public static bool Exists(string key)
        {
            bool result = false;
            if (Cache.TryGetValue(key, out var _))
            {
                result = true;
            }
            return result;
        }



        public static T Get<T>(string key)
        {
            try
            {
                if (CacheEnable())
                {
                    if (Cache.TryGetValue(key, out T result))
                    {
                        return result;
                    }
                    Logger.DebugFormat("Key : {0} does not exists", key);
                }
                return default;
            }
            catch (Exception ex)
            {
                Logger.Fatal($"key:{key},exception:{ex.Message}");
                return default;
            }
        }

        public static bool ClearFromTablePrefix(string key)
        {
            var keyDeleted = false;
            if (CacheEnable())
            {
                var cacheKeys = GetAllKeysList();
                var cacheItem = new List<string>();
                foreach (var cacheKey in cacheKeys)
                {
                    if (cacheKey.StartsWith(key))
                        cacheItem.Add(cacheKey);
                }
                Logger.DebugFormat("Number of Key(s) found {0}, with Prefix {1}", cacheItem.Count, key);

                try
                {
                    foreach (var newkey in cacheItem)
                    {
                        Cache.Remove(key);
                        Logger.DebugFormat("Key : {0} cleared", newkey);

                    }
                    keyDeleted = true;
                }
                catch (Exception ex)
                {
                    Logger.Fatal($"key:{key},exception:{ex.Message}");
                }

            }
            return keyDeleted;
        }



        public static bool RemoveAllCache()
        {
            try
            {
                if (CacheEnable())
                {
                    var cacheKeys = GetAllKeysList();
                    foreach (var cacheKey in cacheKeys)
                    {
                        Cache.Remove(cacheKey);
                    }                    
                }
                return true;
            }
            catch (Exception ex)
            {
                Logger.Fatal(ex.Message);
                return false;
            }
        }      
    }

@Pilchie
Copy link
Member

Pilchie commented May 6, 2020

Glad to hear it!

@ghost ghost locked as resolved and limited conversation to collaborators Jun 5, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants