ASP.NET CORE CACHE的使用(含MemoryCache,Redis)

warrior21st發表於2017-03-17

依賴名稱空間:

Microsoft.AspNetCore.Mvc;//測試呼叫時

Microsoft.Extensions.Caching.Memory;

Microsoft.Extensions.Caching.Redis;

StackExchange.Redis;

Newtonsoft.Json;


定義通用工具類 :CacheUntity

    public class CacheUntity
    {
        private static ICacheHelper _cache = new RedisCacheHelper();//預設使用Redis


        private static bool isInited = false;
        public static void Init(ICacheHelper cache)
        {
            if (isInited)
                return;
            _cache.Dispose();
            _cache = cache;
            isInited = true;
        }


        public static bool Exists(string key)
        {
            return _cache.Exists(key);
        }


        public static T GetCache<T>(string key) where T : class
        {
            return _cache.GetCache<T>(key);
        }


        public static void SetCache(string key, object value)
        {
            _cache.SetCache(key, value);
        }


        public static void SetCache(string key, object value, DateTimeOffset expiressAbsoulte)
        {
            _cache.SetCache(key, value, expiressAbsoulte);
        }


        //public void SetCache(string key, object value, double expirationMinute)
        //{


        //}


        public static void RemoveCache(string key)
        {
            _cache.RemoveCache(key);
        }


    }


定義統一快取操作介面:ICacheHelper

public interface ICacheHelper
    {
        bool Exists(string key);


        T GetCache<T>(string key) where T : class;


        void SetCache(string key, object value);


        void SetCache(string key, object value, DateTimeOffset expiressAbsoulte);//設定絕對時間過期


        //void SetCache(string key, object value, double expirationMinute);  //設定滑動過期, 因redis暫未找到自帶的滑動過期類的API,暫無需實現該介面


        void RemoveCache(string key);


        void Dispose();
    }


定義RedisCache幫助類:RedisCacheHelper 

public class RedisCacheHelper : ICacheHelper
    {
        public RedisCacheHelper(/*RedisCacheOptions options, int database = 0*/)//這裡可以做成依賴注入,但沒打算做成通用類庫,所以直接把連線資訊直接寫在幫助類裡
        {
            RedisCacheOptions options = new RedisCacheOptions();
            options.Configuration = "127.0.0.1:6379";
            options.InstanceName = "test";
            int database = 0;
            _connection = ConnectionMultiplexer.Connect(options.Configuration);
            _cache = _connection.GetDatabase(database);
            _instanceName = options.InstanceName;
        }


        private IDatabase _cache;


        private ConnectionMultiplexer _connection;


        private readonly string _instanceName;


        private string GetKeyForRedis(string key)
        {
            return _instanceName + key;
        }


        public bool Exists(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));


            return _cache.KeyExists(GetKeyForRedis(key));
        }


        public T GetCache<T>(string key) where T : class
        {
            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));


            var value = _cache.StringGet(GetKeyForRedis(key));
            if (!value.HasValue)
                return default(T);


            return JsonConvert.DeserializeObject<T>(value);
        }


        public void SetCache(string key, object value)
        {
            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));
            if (value == null)
                throw new ArgumentNullException(nameof(value));


            if (Exists(GetKeyForRedis(key)))
                RemoveCache(GetKeyForRedis(key));


            _cache.StringSet(GetKeyForRedis(key), JsonConvert.SerializeObject(value));
        }


        public void SetCache(string key, object value, DateTimeOffset expiressAbsoulte)
        {
            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));
            if (value == null)
                throw new ArgumentNullException(nameof(value));


            if (Exists(GetKeyForRedis(key)))
                RemoveCache(GetKeyForRedis(key));


            _cache.StringSet(GetKeyForRedis(key), JsonConvert.SerializeObject(value), expiressAbsoulte - DateTime.Now);
        }


        //public void SetCache(string key, object value, double expirationMinute)
        //{
        //    if (Exists(GetKeyForRedis(key)))
        //        RemoveCache(GetKeyForRedis(key));


        //    DateTime now = DateTime.Now;
        //    TimeSpan ts = now.AddMinutes(expirationMinute) - now;
        //    _cache.StringSet(GetKeyForRedis(key), JsonConvert.SerializeObject(value), ts);
        //}


        public void RemoveCache(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));


            _cache.KeyDelete(GetKeyForRedis(key));
        }


        public void Dispose()
        {
            if (_connection != null)
                _connection.Dispose();
            GC.SuppressFinalize(this);
        }
    }


定義MemoryCache幫助類:MemoryCacheHelper 

public class MemoryCacheHelper : ICacheHelper
    {
        public MemoryCacheHelper(/*MemoryCacheOptions options*/)//這裡可以做成依賴注入,但沒打算做成通用類庫,所以直接把選項直接封在幫助類裡邊
        {
            //this._cache = new MemoryCache(options);
            this._cache = new MemoryCache(new MemoryCacheOptions());
        }


        private IMemoryCache _cache;


        public bool Exists(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));


            object v = null;
            return this._cache.TryGetValue<object>(key, out v);
        }


        public T GetCache<T>(string key) where T : class
        {
            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));


            T v = null;
            this._cache.TryGetValue<T>(key, out v);


            return v;
        }


        public void SetCache(string key, object value)
        {
            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));
            if (value == null)
                throw new ArgumentNullException(nameof(value));


            object v = null;
            if (this._cache.TryGetValue(key, out v))
                this._cache.Remove(key);
            this._cache.Set<object>(key, value);
        }


        public void SetCache(string key, object value, double expirationMinute)
        {
            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));
            if (value == null)
                throw new ArgumentNullException(nameof(value));


            object v = null;
            if (this._cache.TryGetValue(key, out v))
                this._cache.Remove(key);
            DateTime now = DateTime.Now;
            TimeSpan ts = now.AddMinutes(expirationMinute) - now;
            this._cache.Set<object>(key, value, ts);
        }


        public void SetCache(string key, object value, DateTimeOffset expirationTime)
        {
            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));
            if (value == null)
                throw new ArgumentNullException(nameof(value));


            object v = null;
            if (this._cache.TryGetValue(key, out v))
                this._cache.Remove(key);


            this._cache.Set<object>(key, value, expirationTime);
        }


        public void RemoveCache(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));


            this._cache.Remove(key);
        }


        public void Dispose()
        {
            if (_cache != null)
                _cache.Dispose();
            GC.SuppressFinalize(this);
        }
    }


呼叫:

        [HttpGet]
        public string TestCache()
        {
            CacheUntity.SetCache("test", "RedisCache works!");
            string res = CacheUntity.GetCache<string>("test");
            res += Environment.NewLine;


            CacheUntity.Init(new MemoryCacheHelper());
            CacheUntity.SetCache("test", "MemoryCache works!");
            res += CacheUntity.GetCache<string>("test");


            return res;
        }

相關文章