ASP.NET Core-内存缓存与分布式缓存(IMemoryCache、IDistributedCache)

IMemoryCache:内存缓存接口,内存缓存可以存储任何对象,存储形式键值对

IDistributedCache:分布式缓存接口(Redis、MongoDB、DB...)

 IDistributedCache:

public interface IDistributedCache
    {
     //获取
byte[] Get(string key); Task<byte[]> GetAsync(string key, CancellationToken token = default(CancellationToken)); //刷新并重置其过期超时的值(如果有) void Refresh(string key); Task RefreshAsync(string key, CancellationToken token = default(CancellationToken)); //删除 void Remove(string key); Task RemoveAsync(string key, CancellationToken token = default(CancellationToken)); //添加 void Set(string key, byte[] value, DistributedCacheEntryOptions options); Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default(CancellationToken)); }

MemoryCache内存缓存使用步骤:

1、安装程序集:System.Runtime.Caching 和 Microsoft.Extensions.Caching.Memory,如果是是Core MVC程序自带的Microsoft.AspNetCore.App包里已经涵盖了 Microsoft.Extensions.Caching.Memory,无需重复下载。

2、在ConfigureService中注册内存缓存服务: services.AddMemoryCache();

3、构造函数注入 IMemoryCache

Redis缓存使用步骤:

安装 Microsoft.Extensions.Caching.Redis包,

直接使用:(RedisCache实现了接口IDistributedCache)

static void Main(string[] args)
        {
            RedisCache redisCache = new RedisCache(new RedisCacheOptions() {
                Configuration="192.168.254.134:6379",
                InstanceName="test"
            });
            redisCache.SetString("key","value");
            var val = redisCache.GetString("key");
        }

在MVC中使用,ConfigureService中添加以下代码:

//将Redis分布式缓存服务添加到服务中
            services.AddDistributedRedisCache(options =>
            {
                //options.Configuration = "139.155.44.138:6379";
                //Redis实例名
                options.InstanceName = "RedisDistributedCache";
                options.ConfigurationOptions = new ConfigurationOptions()
                {
                    ConnectTimeout = 2000,
                    DefaultDatabase = 1,
                    //Password = "xxxxxx",
                    AllowAdmin = true,
                    AbortOnConnectFail = false,//当为true时,当没有可用的服务器时则不会创建一个连接
                    
                };                
                options.ConfigurationOptions.EndPoints.Add("139.155.44.138:6379");
            });

需要缓存的服务中注入IDistributedCache即可:

  public HomeController(IDistributedCache Cache){}  

MongoDB缓存使用步骤:

安装 MarkCBB.Extensions.Caching.MongoDB 包

直接使用:

static void Main(string[] args)
        {
            MongoDBCache mongoDBCache = new MongoDBCache(new MongoDBCacheOptions()
            {
                ConnectionString = "mongodb://192.168.254.135:27017",
                DatabaseName = "sample",
                CollectionName = "sample"
            });

            mongoDBCache.Set("username", Encoding.UTF8.GetBytes("jack"), new DistributedCacheEntryOptions()
            {
                AbsoluteExpiration = DateTime.Now.AddDays(1)
            });

            var info = mongoDBCache.GetString("username");

        }

 案例1:使用ICaching接口封装MemoryCache、RedisCache操作。自己选择内存或分布式缓存

ICaching接口:

public interface ICaching
    {
        T GetOrSetObjectFromCache<T>(string cacheItemName, Func<T> objectSettingFunction, int cacheTimeInMinutes = 0);

        void SetValueToCache(string key, object value, int cacheTimeInMinutes = 120);
void Invalidate(string key); void InvalidateAll(); object GetValueFromCache(string key); }

MemoryCaching、RedisCaching实现类:

    /// <summary>
    /// EasyMemoryCache
    /// https://github.com/thiagoloureiro/EasyMemoryCache
    /// </summary>
    public class MemoryCaching : ICaching, IDisposable
    {
        private readonly MemoryCache _myCache = new MemoryCache(new MemoryCacheOptions());
        private readonly IConfiguration _configuration;
        private readonly int _cacheTime;

        public MemoryCaching(IConfiguration configuration)
        {
            this._configuration = configuration;
            _cacheTime = this._configuration.GetValue<int>("CACHE_TIME");
        }

        public void Dispose()
        {
            this._myCache?.Dispose();
        }

        public T GetOrSetObjectFromCache<T>(string cacheItemName, Func<T> objectSettingFunction, int cacheTimeInMinutes = 0)
        {
            T cacheObject = default(T);

            var cacheObj = this._myCache.Get(cacheItemName);
            if (cacheObj != null)
            {
                cacheObject = (T)cacheObj;
            }
            else
            {
                cacheObject = objectSettingFunction();
                this._myCache.Set(cacheItemName, cacheObject, DateTime.Now.AddMinutes(cacheTimeInMinutes == 0 ? _cacheTime : cacheTimeInMinutes));
            }
            return cacheObject;
        }

        public void SetValueToCache(string key, object value, int cacheTimeInMinutes = 120)
        {
            this._myCache.Set(key, value, DateTimeOffset.Now.AddMinutes(cacheTimeInMinutes));
        }


        public object GetValueFromCache(string key)
        {
            return this._myCache.Get(key);
        }

        public void Invalidate(string key)
        {
            this._myCache.Remove(key);
        }

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

                foreach (var item in items)
                {
                    this._myCache.Remove(item);
                }
            }
        }

    }

    /// <summary>
    /// RedisCache
    /// </summary>
    public class RedisCaching : ICaching, IDisposable
    {
        private readonly IDistributedCache _myCache;// = new RedisCache(new RedisCacheOptions());
        private readonly IConfiguration _configuration;
        private readonly int _cacheTime;

        public RedisCaching(IConfiguration configuration, IDistributedCache cache)
        {
            this._configuration = configuration;
            _cacheTime = this._configuration.GetValue<int>("CACHE_TIME");
            _myCache = cache;
        }

        public void Dispose()
        {
            //this._myCache?.Dispose();
        }

        public T GetOrSetObjectFromCache<T>(string cacheItemName, Func<T> objectSettingFunction, int cacheTimeInMinutes = 0)
        {
            T cacheObject = default(T);
            byte[] cacheObj = this._myCache.Get(cacheItemName);
                
            if (cacheObj != null)
            {
                var stringObject = Encoding.UTF8.GetString(cacheObj);//通过UTF-8编码,将字节数组反序列化为Json字符串
                cacheObject = JsonConvert.DeserializeObject<T>(stringObject, new JsonSerializerSettings()
                {
                    TypeNameHandling = TypeNameHandling.All
                });
            }
            else
            {
                cacheObject = objectSettingFunction();
                var stringObject = JsonConvert.SerializeObject(cacheObject, new JsonSerializerSettings()
                {
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                    TypeNameHandling = TypeNameHandling.All
                });

                var bytesObject = Encoding.UTF8.GetBytes(stringObject);//将Json字符串通过UTF-8编码,序列化为字节数组

                this._myCache.Set(cacheItemName, bytesObject, new DistributedCacheEntryOptions() { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(cacheTimeInMinutes == 0 ? _cacheTime : cacheTimeInMinutes) });
            }
            this._myCache.Refresh(cacheItemName);
            return cacheObject;
        }

        public void SetValueToCache(string key, object value, int cacheTimeInMinutes = 120)
        {
            var stringObject = JsonConvert.SerializeObject(value, new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                TypeNameHandling = TypeNameHandling.All
            });

            var bytesObject = Encoding.UTF8.GetBytes(stringObject);//将Json字符串通过UTF-8编码,序列化为字节数组
            this._myCache.Set(key, bytesObject, new DistributedCacheEntryOptions() { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(cacheTimeInMinutes) });
        }


        /// <summary>
        /// 从Redis中刷新键值
        /// </summary>
        /// <param name="key">缓存键</param>
        public void Refresh(string key)
        {
            this._myCache.Refresh(key);
        }


        public object GetValueFromCache(string key)
        {
            return this._myCache.Get(key);
        }

        public void Invalidate(string key)
        {
            this._myCache.Remove(key);
        }

        public void InvalidateAll()
        {
            throw new NotImplementedException();
        }


    }
View Code

ConfigureServices:

services.AddDistributedRedisCache(options =>
            {
                ConfigurationOptions configurationOptions = new ConfigurationOptions
                {
                    ConnectTimeout = 2000,
                    DefaultDatabase = 1,                    
                    Password = "315360007",
                    AllowAdmin = true,
                    AbortOnConnectFail = false//当为true时,当没有可用的服务器时则不会创建一个连接
                };
                configurationOptions.EndPoints.Add("192.168.0.82:16379");
                options.ConfigurationOptions = configurationOptions;
            });

services.AddSingleton(typeof(ICaching), typeof(MemoryCaching));
//services.AddSingleton(typeof(ICaching), typeof(RedisCaching));
View Code

未完待续...

原文地址:https://www.cnblogs.com/fanfan-90/p/12151924.html