前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >asp.net core 上使用redis探索(3)--redis示例demo

asp.net core 上使用redis探索(3)--redis示例demo

作者头像
Ryan_OVO
发布于 2023-10-19 11:20:29
发布于 2023-10-19 11:20:29
31200
代码可运行
举报
文章被收录于专栏:程序随笔程序随笔
运行总次数:0
代码可运行

由于是基于.net-core平台,所以,我们最好是基于IDistributedCache接口来实现。ASP.NET-CORE下的官方redis客户端实现是基于StackExchange的。但是官方提供的IDistributeCache接口中的方法只是增删改查,我们可以继续拓展,增加订阅/发布,消息队列,当然这些方法必须是基于底层的StackExchange相对应的方法来做的。 如果我们要实现自己的Redis客户端,同时不使用底层的StackExchange驱动,可以派生一个继承自IDistributedCache的接口,定义自己需要的方法,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IServiceStackRedisCache : IDistributedCache
{
    void Delete<T>(T item); // 删除
    void DeleteAll<T>(T item);
    T Get<T>(string id);
    IQueryable<T> GetAll<T>();
    IQueryable<T> GetAll<T>(string hash, string value);
    IQueryable<T> GetAll<T>(string hash, string value, Expression<Func<T, bool>> filter);
    long PublishMessage(string channel, object item);
    void Set<T>(T item);
    void Set<T>(T item, List<string> hash, List<string> value, string keyName);
    void Set<T>(T item, string hash, string value, string keyName);
    void SetAll<T>(List<T> listItems);
    void SetAll<T>(List<T> list, List<string> hash, List<string> value, string keyName);
    void SetAll<T>(List<T> list, string hash, string value, string keyName);
}

接口有了,接下来就是继承自接口的类,我们定义一个类来实现接口里的方法,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using ServiceStack.Redis;

namespace Microsoft.Extensions.Caching.Redis
{
    public class ServiceStackRedisCache : IServiceStackRedisCache
    {
        private readonly IRedisClientsManager _redisManager;
        private readonly ServiceStackRedisCacheOptions _options;

        public ServiceStackRedisCache(IOptions<ServiceStackRedisCacheOptions> optionsAccessor)
        {
            if (optionsAccessor == null)
            {
                throw new ArgumentNullException(nameof(optionsAccessor));
            }

            _options = optionsAccessor.Value;

            var host = $"{_options.Password}@{_options.Host}:{_options.Port}";
            RedisConfig.VerifyMasterConnections = false;
            _redisManager = new RedisManagerPool(host);
        }
        #region Base

        public byte[] Get(string key)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            using (var client = _redisManager.GetClient() as IRedisNativeClient)
            {
                if (client.Exists(key) == 1)
                {
                    return client.Get(key);
                }
            }
            return null;
        }

        public async Task<byte[]> GetAsync(string key)
        {
            return Get(key);
        }

        public void Set(string key, byte[] value, DistributedCacheEntryOptions options)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            using (var client = _redisManager.GetClient() as IRedisNativeClient)
            {
                var expireInSeconds = GetExpireInSeconds(options);
                if (expireInSeconds > 0)
                {
                    client.SetEx(key, expireInSeconds, value);
                    client.SetEx(GetExpirationKey(key), expireInSeconds, Encoding.UTF8.GetBytes(expireInSeconds.ToString()));
                }
                else
                {
                    client.Set(key, value);
                }
            }
        }

        public async Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options)
        {
            Set(key, value, options);
        }

        public void Refresh(string key)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            using (var client = _redisManager.GetClient() as IRedisNativeClient)
            {
                if (client.Exists(key) == 1)
                {
                    var value = client.Get(key);
                    if (value != null)
                    {
                        var expirationValue = client.Get(GetExpirationKey(key));
                        if (expirationValue != null)
                        {
                            client.Expire(key, int.Parse(Encoding.UTF8.GetString(expirationValue)));
                        }
                    }
                }
            }
        }

        public async Task RefreshAsync(string key)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            Refresh(key);
        }

        public void Remove(string key)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            using (var client = _redisManager.GetClient() as IRedisNativeClient)
            {
                client.Del(key);
            }
        }

        public async Task RemoveAsync(string key)
        {
            Remove(key);
        }

        private int GetExpireInSeconds(DistributedCacheEntryOptions options)
        {
            if (options.SlidingExpiration.HasValue)
            {
                return (int)options.SlidingExpiration.Value.TotalSeconds;
            }
            else if (options.AbsoluteExpiration.HasValue)
            {
                return (int)options.AbsoluteExpirationRelativeToNow.Value.TotalSeconds;
            }
            else
            {
                return 0;
            }
        }

        private string GetExpirationKey(string key)
        {
            return key + $"-{nameof(DistributedCacheEntryOptions)}";
        }
        #endregion
        #region data
        public T Get<T>(string id)
        {
            using (var redisClient = _redisManager.GetClient())
            {
                var redis = redisClient.As<T>();
                return redis.GetById(id.ToLower());
            }
        }

        public IQueryable<T> GetAll<T>()
        {
            using (var redisClient = _redisManager.GetClient())
            {
                var redis = redisClient.As<T>();
                return redis.GetAll().AsQueryable();
            }
        }

        public IQueryable<T> GetAll<T>(string hash, string value, Expression<Func<T, bool>> filter)
        {
            var filtered = _redisManager.GetClient().GetAllEntriesFromHash(hash).Where(c => c.Value.Equals(value, StringComparison.CurrentCultureIgnoreCase));
            var ids = filtered.Select(c => c.Key);

            var ret = _redisManager.GetClient().As<T>().GetByIds(ids).AsQueryable()
                                .Where(filter);

            return ret;
        }

        public IQueryable<T> GetAll<T>(string hash, string value)
        {
            var filtered = _redisManager.GetClient().GetAllEntriesFromHash(hash).Where(c => c.Value.Equals(value, StringComparison.CurrentCultureIgnoreCase));
            var ids = filtered.Select(c => c.Key);

            var ret = _redisManager.GetClient().As<T>().GetByIds(ids).AsQueryable();
            return ret;
        }

        public void Set<T>(T item)
        {
            using (var redisClient = _redisManager.GetClient())
            {
                var redis = redisClient.As<T>();
                redis.Store(item);
            }
        }

        public void Set<T>(T item, string hash, string value, string keyName)
        {
            Type t = item.GetType();
            PropertyInfo prop = t.GetProperty(keyName);

            _redisManager.GetClient().SetEntryInHash(hash, prop.GetValue(item).ToString(), value.ToLower());

            _redisManager.GetClient().As<T>().Store(item);
        }

        public void Set<T>(T item, List<string> hash, List<string> value, string keyName)
        {
            Type t = item.GetType();
            PropertyInfo prop = t.GetProperty(keyName);

            for (int i = 0; i < hash.Count; i++)
            {
                _redisManager.GetClient().SetEntryInHash(hash[i], prop.GetValue(item).ToString(), value[i].ToLower());
            }

            _redisManager.GetClient().As<T>().Store(item);
        }

        public void SetAll<T>(List<T> listItems)
        {
            using (var redisClient = _redisManager.GetClient())
            {
                var redis = redisClient.As<T>();
                redis.StoreAll(listItems);
            }
        }

        public void SetAll<T>(List<T> list, string hash, string value, string keyName)
        {
            foreach (var item in list)
            {
                Type t = item.GetType();
                PropertyInfo prop = t.GetProperty(keyName);

                _redisManager.GetClient().SetEntryInHash(hash, prop.GetValue(item).ToString(), value.ToLower());

                _redisManager.GetClient().As<T>().StoreAll(list);
            }
        }

        public void SetAll<T>(List<T> list, List<string> hash, List<string> value, string keyName)
        {
            foreach (var item in list)
            {
                Type t = item.GetType();
                PropertyInfo prop = t.GetProperty(keyName);

                for (int i = 0; i < hash.Count; i++)
                {
                    _redisManager.GetClient().SetEntryInHash(hash[i], prop.GetValue(item).ToString(), value[i].ToLower());
                }

                _redisManager.GetClient().As<T>().StoreAll(list);
            }
        }

        public void Delete<T>(T item)
        {
            using (var redisClient = _redisManager.GetClient())
            {
                var redis = redisClient.As<T>();
                redis.Delete(item);
            }
        }

        public void DeleteAll<T>(T item)
        {
            using (var redisClient = _redisManager.GetClient())
            {
                var redis = redisClient.As<T>();
                redis.DeleteAll();
            }
        }

        public long PublishMessage(string channel, object item)
        {
            var ret = _redisManager.GetClient().PublishMessage(channel, JsonConvert.SerializeObject(item));
            return ret;
        }

        #endregion
    }
}

在这里我们使用ServiceStack来作为底层redis驱动。在构造函数中根据配置连接redis服务器

aps.net-core给我们提供了强大的配置功能,使用强类型的Options,一般,我们实现一个继承自IOptions<TOptions>的类。定义一些字段用来表示主机,端口等常规redis配置选项。由于IOptions接口定义了一个Value属性,我们可以通过这个属性来获取配置类的实例。 然后我们在redis客户端类中(也就是上面的ServiceStackRedisCache类),使用构造函数注入。这样就能获取到redis的配置了。 然后我们在控制器的构造函数中注入redis客户端类实例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private readonly IServiceStackRedisCache _cache;
public ValuesController(IServiceStackRedisCache cache)
{
    _cache = cache;
}

如此,我们才能使用redis客户端去操作redis服务器。 最后就是最重要的部分了。ASP.NET-CORE框架随处可见的都是依赖注入。上面所有的程序,都是一个接口对应着一个类。所谓的依赖注入,其实就是继承自接口的类的实例化过程,但是这个过程是解耦的!DI的作用主要就是用来解耦实例化的过程。 ASP.NET-CORE框架依赖注入部分是在ConfigureService中使用的。 从上面的过程中,我们看到有两个构造函数的注入过程,因此,我们需要实现两个DI,分别是配置类的DI和redis客户端类的DI。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
services.Configure(setupAction);

services.Add(ServiceDescriptor.Singleton<IServiceStackRedisCache, ServiceStackRedisCache>());

整个步骤就是: 1.定义接口,用于继承IDistributedCache的接口。该接口主要封装了基本的redis操作。 2.实现接口,实现redis的各个逻辑。 3.基于IOptions<TOptions>接口实现redis的常规配置。 4.在控制器的构造函数中注入。 5.依赖注入以上接口的实例。

完整demo下载:链接:https://pan.baidu.com/s/17w0c0y9_VF3TzvgilgazjQ 密码:4u5e

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-05-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
asp.net core上使用Redis探索(2)
在<<asp.net core上使用Redis探索(1)>>中,我介绍了一个微软官方实现Microsoft.Extensions.Caching.Redis的类库,这次,我们使用微软官方的Redis客户端。
Ryan_OVO
2023/10/19
3080
asp.net性能优化之使用Redis缓存(入门)
1.1对于大量的数据读取,为了缓解数据库的压力将一些不经常变化的而又读取频繁的数据存入redis缓存
张哥编程
2024/12/21
910
C# 通过ServiceStack 操作Redis——String类型的使用及示例
我这里就用别人已经封装好的Reids操作类来和大家一起参考了下,看看怎么使用ServiceStack.Redis 操作Redis数据
明志德道
2023/10/21
3710
C# 通过ServiceStack 操作Redis——String类型的使用及示例
Asp.Net Core 轻松学-正确使用分布式缓存
    本来昨天应该更新的,但是由于各种原因,抱歉,让追这个系列的朋友久等了。上一篇文章 在.Net Core 使用缓存和配置依赖策略 讲的是如何使用本地缓存,那么本篇文章就来了解一下如何使用分布式缓存,通过本章,你将了解到如何使用分布式缓存,以及最重要的是,如何选择适合自己的分布式缓存;本章主要包含两个部分:
梁规晓
2019/04/11
1.5K0
Asp.Net Core 轻松学-正确使用分布式缓存
分布式中使用Redis实现Session共享(一)
用户1168362
2018/01/05
2.3K0
分布式中使用Redis实现Session共享(一)
Redis基本使用及百亿数据量中的使用技巧分享
熟悉的开场白,大家晚上好啊,今天给大家分享的是Redis在大数据中的使用,可能真正讲的是一些redis的使用技巧,Redis基本的一些东西。
依乐祝
2018/11/12
1K0
【愚公系列】2023年01月 .NET CORE工具案例-基于Redis和Sql Server分布式缓存
缓存这种能够提升指令和数据读取速度的特性,随着本地计算机系统向分布式系统的扩展,在分布式计算领域中得到了广泛的应用,称为分布式缓存。
愚公搬代码
2023/03/16
7500
【愚公系列】2023年01月 .NET CORE工具案例-基于Redis和Sql Server分布式缓存
【愚公系列】2022年12月 Redis数据库-缓存雪崩和缓存穿透问题的解决
文章目录 前言 一、缓存雪崩和缓存穿透问题的解决 1.IMemoryCache的改造 1.1 解决方案 1.2 依赖 1.3 解决思路 1.4 具体代码 2.IDistributedCache的改造
愚公搬代码
2022/12/09
5540
【愚公系列】2022年12月 Redis数据库-缓存雪崩和缓存穿透问题的解决
.net core redis的全套操作
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
hailang2zh
2019/08/29
1.5K0
.net core redis的全套操作
ASP.NET Core微服务(六)——【redis操作】
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。
红目香薰
2022/11/28
6580
Redis系列(二)-Hredis客户端设计及开源
接上篇c#实现redis客户端(一),重新整理些了下。 项目说明 背景:因为有地方要用,而又没找到对sentinel良好支持的Net客户端,所以就简单重写了个。 目标:尽可能的简单,轻量级,不进行过度的封装,使用方便。 代码说明:         1. 与Redis服务端的Socket通信、协议格式封装。在RedisBaseClient里          2. 只对Set、Get封装,暴露出Send接口。在RedisCommand里面添加自己想要的支持。 var info = rcClient
蘑菇先生
2018/05/21
9170
.Net Core使用Redis的一个入门简单Demo
本例子讲述一个在.Net core环境中对Redis数据库进行增删改查操作。 首先,要安装好Redis数据库,至于怎么安装,本文不再赘述,可以自行百度,有很详细的教程。 安装好之后,在CMD中输入
码农阿宇
2018/04/18
8130
.Net Core使用Redis的一个入门简单Demo
.net core HttpClient 使用之掉坑解析(一)
在我们开发当中经常需要向特定URL地址发送Http请求操作,在.net core 中对httpClient使用不当会造成灾难性的问题,这篇文章主要来分享.net core中通过IHttpClientFactory 工厂来使用HttpClient的正确打开方式。
Jlion
2022/04/07
9910
.net core HttpClient 使用之掉坑解析(一)
C# 通过ServiceStack 操作Redis——Hash类型的使用及示例
Hash:结构 key-key-value,通过索引快速定位到指定元素的,可直接修改某个字段
明志德道
2023/10/21
4500
C# 通过ServiceStack 操作Redis——Hash类型的使用及示例
《ASP.NET Core 与 RESTful API 开发实战》-- (第7章)-- 读书笔记(上)
缓存是一种通过存储资源的备份,在请求时返回资源备份的技术。ASP.NET Core 支持多种形式的缓存,既支持基于 HTTP 的缓存,也支持内存缓存和分布式缓存,还提供响应缓存中间件
郑子铭
2021/01/13
5860
《ASP.NET Core 与 RESTful API 开发实战》-- (第7章)-- 读书笔记(上)
教你写个简单的 Redis Client 框架 - .NET Core
最近叶老板写了个 FreeRedis,刚好前段时间在学习 Redis,于是跟风试试也写一个简单的 RedisClient。目前 FreeRedis 处于初级阶段,需要更多人的参与、测试,有兴趣大家一起参与贡献:
痴者工良
2021/04/26
1.3K0
Redis 入门与 ASP.NET Core 缓存
如果你还没有 redis 集群,可以参考笔者的另一篇文章:搭建分布式 Redis Cluster 集群与 Redis 入门
痴者工良
2021/04/26
2.1K0
使用redis生成唯一编号
在项目开发中,我们需要保证数据的唯一性,就目前开发中常用的方式有使用自增序列、GUID、时间戳以及时间戳加上随机数。生成ID的方法有很多,每种适用场景、需求以及性能要求不同。下面我们列出以下较为常用的生成ID的方式,并且来讨论以下他们的优缺点。
喵叔
2021/11/30
2.4K0
.Net Core下 Redis的String Hash List Set和Sorted Set的例子
1.新建一个.Net Core控制台应用程序,用Nuget导入驱动 打开程序包管理控制台, 执行以下代码。 PM> Install-Package ServiceStack.Redis 即可添
码农阿宇
2018/04/18
1.2K0
.Net Core下 Redis的String  Hash List Set和Sorted Set的例子
asp.net core 系列之Response caching 之 Distributed caching(3)
这篇文章讲解分布式缓存,即 Distributed caching in ASP.NET Core
Vincent-yuan
2019/09/11
1.1K0
asp.net core 系列之Response caching 之 Distributed caching(3)
推荐阅读
相关推荐
asp.net core上使用Redis探索(2)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验