九、.net core(.NET 6)添加通用的Redis功能
.net core 编写通用的Redis功能
在 Package项目里面,添加包:StackExchange.Redis:

在Common工具文件夹下,新建 Wsk.Core.Redis类库项目,并新建 RedisManage 类和对应接口 IRedisManage,如下图。然后,在该项目里面,引用共用包项目Wsk.Core.Package,用以使用Redis有关功能。

在RedisManage类里面,新增几个用于连接Redis配置的全局变量,以及一个构造函数:

在配置文件里面,新建Redis的有关配置信息:

配置的Json文本:
"Redis": [
{
"Name": "Wesky",
"Ip": "127.0.0.1",
"Port": 6379,
"Password": "wesky123",
"Timeout": 30,
"Db": 3
}
]
其中,Name是别名,可以任意起。Ip是Redis的服务端地址,例如安装本地,就是127.0.0.1,端口号Port默认是6379,密码可以通过Redis安装的根目录下的配置文件进行设置,Timeout是连接的超时时间,Db是使用Redis的DB区,一般Redis的DB区默认是0到15。注意:此处的配置使用的是数组,用于将来进行Redis分布式操作的可拓展。
看下redis安装目录下的配置文件局部一览:

如果打算修改该配置文件来实现修改有关的配置信息,但是没有效果,注意在windows服务里面把redis服务进行重新启动。如果还不行,就把另外一个conf配置文件也做同样的操作,然后再重启redis服务。
接着,在解决方案下,新建一个文件夹,叫DataEntities,该文件夹当做将来存放各种实体类或有关项目的目录。现在咱们在该新建的文件夹下,新建一个类库项目:Wsk.Core.Entity,然后新建一个实体类,叫RedisConfig,用于读取到配置文件的Redis信息进行赋值使用:

回到Redis类库项目,在RedisManage类里面,添加一个方法ReadRedisSetting,用于读取该配置信息,并赋值给ConfigurationOptions类:

ReadRedisSetting代码:

private ConfigurationOptions ReadRedisSetting()
{
try
{
List<RedisConfig> config = AppHelper.ReadAppSettings<RedisConfig>(new string[] { "Redis" }); // 读取Redis配置信息
if (config.Any())
{
ConfigurationOptions options = new ConfigurationOptions
{
EndPoints =
{
{
config.FirstOrDefault().Ip,
config.FirstOrDefault().Port
}
},
ClientName = config.FirstOrDefault().Name,
Password = config.FirstOrDefault().Password,
ConnectTimeout = config.FirstOrDefault().Timeout,
DefaultDatabase = config.FirstOrDefault().Db,
};
return options;
}
return null;
}
catch(Exception ex)
{
_logger.LogError($"获取Redis配置信息失败:{ex.Message}");
return null;
} }
然后,新建一个方法ConnectionRedis,用于连接Redis:

方法代码:

private ConnectionMultiplexer ConnectionRedis()
{
if (this._redisConnection != null && this._redisConnection.IsConnected)
{
return this._redisConnection; // 已有连接,直接使用
}
lock (_redisConnectionLock)
{
if (this._redisConnection != null)
{
this._redisConnection.Dispose(); // 释放,重连
}
try
{
this._redisConnection = ConnectionMultiplexer.Connect(_configOptions);
}
catch (Exception ex)
{
_logger.LogError($"Redis服务启动失败:{ex.Message}");
}
}
return this._redisConnection;
}
在构造函数里面,进行Redis连接的实现:

现在,做个简单的测试,新建一个Set方法和一个GetValue方法,用于测试效果:

在IRedisMagane接口里面,添加以上有关的接口方法:

现在转到启动项目上,启动项目新增对Wsk.Core.Redis项目的引用,并且在WskService类下面,新增对刚刚新增的Redis管理类的依赖注入的注册:

现在,在控制器里面,添加有关构造函数的依赖注入,然后做个实践,验证下是否成功。
先改写控制器内容,先设置一对key/value,然后进行读取并返回:

启动项目,输入Hello Redis! ,然后查看返回对应的内容:

我们打开Redis管理客户端看看,是不是可以看见有这个值:

因为我们配置的是Db = 3,所以在Db3这个地方,可以看见我们的Key,点击Tesk,即可在右边窗口看见对应的内容。说明Redis操作成功。
最后,咱们对Redis管理类进行一些其他功能的添加,以及接口方法的添加,用于完善它的功能链,包括移除、读取实体数据、清空、异步操作等。以下截图为对应的接口方法展示:

接口部分源码:

public interface IRedisManage
{
/// <summary>
/// 设置一个 键值对
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="ts"></param>
void Set(string key, object value, TimeSpan ts);
/// <summary>
/// //获取 Reids 缓存值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
string GetValue(string key);
/// <summary>
/// 获取序列化值
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
TEntity Get<TEntity>(string key);
/// <summary>
/// 判断Key是否存在
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
bool Get(string key);
/// <summary>
/// 移除某个Key和值
/// </summary>
/// <param name="key"></param>
void Remove(string key);
/// <summary>
/// 清空Redis
/// </summary>
void Clear();
/// <summary>
/// 异步获取 Reids 缓存值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
Task<string> GetValueAsync(string key);
/// <summary>
/// 异步获取序列化值
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
Task<TEntity> GetAsync<TEntity>(string key);
Task SetAsync(string key, object value, TimeSpan cacheTime);
Task<bool> GetAsync(string key);
/// <summary>
/// 异步移除指定的key
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
Task RemoveAsync(string key);
/// <summary>
/// 异步移除模糊查询到的key
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
Task RemoveByKey(string key);
/// <summary>
/// 异步全部清空
/// </summary>
/// <returns></returns>
Task ClearAsync();
}
接口实现部分的整体源码:

public class RedisManage : IRedisManage
{
public volatile ConnectionMultiplexer _redisConnection;
private readonly object _redisConnectionLock = new object();
private readonly ConfigurationOptions _configOptions;
private readonly ILogger<RedisManage> _logger;
public RedisManage(ILogger<RedisManage> logger)
{
_logger = logger;
ConfigurationOptions options = ReadRedisSetting();
if (options == null)
{
_logger.LogError("Redis数据库配置有误");
} this._configOptions = options;
this._redisConnection = ConnectionRedis();
} private ConfigurationOptions ReadRedisSetting()
{
try
{
List<RedisConfig> config = AppHelper.ReadAppSettings<RedisConfig>(new string[] { "Redis" }); // 读取Redis配置信息
if (config.Any())
{
ConfigurationOptions options = new ConfigurationOptions
{
EndPoints =
{
{
config.FirstOrDefault().Ip,
config.FirstOrDefault().Port
}
},
ClientName = config.FirstOrDefault().Name,
Password = config.FirstOrDefault().Password,
ConnectTimeout = config.FirstOrDefault().Timeout,
DefaultDatabase = config.FirstOrDefault().Db,
};
return options;
}
return null;
}
catch(Exception ex)
{
_logger.LogError($"获取Redis配置信息失败:{ex.Message}");
return null;
} } private ConnectionMultiplexer ConnectionRedis()
{
if (this._redisConnection != null && this._redisConnection.IsConnected)
{
return this._redisConnection; // 已有连接,直接使用
}
lock (_redisConnectionLock)
{
if (this._redisConnection != null)
{
this._redisConnection.Dispose(); // 释放,重连
}
try
{
this._redisConnection = ConnectionMultiplexer.Connect(_configOptions);
}
catch (Exception ex)
{
_logger.LogError($"Redis服务启动失败:{ex.Message}");
}
}
return this._redisConnection;
} public string GetValue(string key)
{
return _redisConnection.GetDatabase().StringGet(key);
} public void Set(string key, object value, TimeSpan ts)
{
if (value != null)
{
_redisConnection.GetDatabase().StringSet(key, JsonConvert.SerializeObject(value), ts);
}
} public void Clear()
{
foreach (var endPoint in this.ConnectionRedis().GetEndPoints())
{
var server = this.ConnectionRedis().GetServer(endPoint);
foreach (var key in server.Keys())
{
_redisConnection.GetDatabase().KeyDelete(key);
}
}
} public bool Get(string key)
{
return _redisConnection.GetDatabase().KeyExists(key);
} public TEntity Get<TEntity>(string key)
{
var value = _redisConnection.GetDatabase().StringGet(key);
if (value.HasValue)
{
//需要用的反序列化,将Redis存储的Byte[],进行反序列化
return JsonConvert.DeserializeObject<TEntity>(value);
}
else
{
return default(TEntity);
}
} public void Remove(string key)
{
_redisConnection.GetDatabase().KeyDelete(key);
} public bool SetValue(string key, byte[] value)
{
return _redisConnection.GetDatabase().StringSet(key, value, TimeSpan.FromSeconds(120));
} public async Task ClearAsync()
{
foreach (var endPoint in this.ConnectionRedis().GetEndPoints())
{
var server = this.ConnectionRedis().GetServer(endPoint);
foreach (var key in server.Keys())
{
await _redisConnection.GetDatabase().KeyDeleteAsync(key);
}
}
} public async Task<bool> GetAsync(string key)
{
return await _redisConnection.GetDatabase().KeyExistsAsync(key);
} public async Task<string> GetValueAsync(string key)
{
return await _redisConnection.GetDatabase().StringGetAsync(key);
} public async Task<TEntity> GetAsync<TEntity>(string key)
{
var value = await _redisConnection.GetDatabase().StringGetAsync(key);
if (value.HasValue)
{
return JsonConvert.DeserializeObject<TEntity>(value);
}
else
{
return default;
}
} public async Task RemoveAsync(string key)
{
await _redisConnection.GetDatabase().KeyDeleteAsync(key);
} public async Task RemoveByKey(string key)
{
var redisResult = await _redisConnection.GetDatabase().ScriptEvaluateAsync(LuaScript.Prepare(
//模糊查询:
" local res = redis.call('KEYS', @keypattern) " +
" return res "), new { @keypattern = key }); if (!redisResult.IsNull)
{
var keys = (string[])redisResult;
foreach (var k in keys)
_redisConnection.GetDatabase().KeyDelete(k); }
} public async Task SetAsync(string key, object value, TimeSpan cacheTime)
{
if (value != null)
{
await _redisConnection.GetDatabase().StringSetAsync(key, JsonConvert.SerializeObject(value), cacheTime);
}
} public async Task<bool> SetValueAsync(string key, byte[] value)
{
return await _redisConnection.GetDatabase().StringSetAsync(key, value, TimeSpan.FromSeconds(120));
} }
由于时间关系,就不一一列举各自的功能了,各位大佬们可以自行尝试。
最后,说个小窍门:Key值如果使用冒号,在客户端上面查看就会自动变成分层结构。举个例子,改写控制器,原本设置的Test这个Key,改写为Test:Wesky:

然后,启动程序,让他执行一下,用于生成一条记录,例如此处我写入:Hello Key’s Rules:

由此可见,Key值分层显示了。在一些场合下,可以使用冒号来分隔开不同层级的Key,以便于在客户端查看。
至此,结束,欢迎打赏、评论和点赞。
版权所有,转载请注明出处:https://www.cnblogs.com/weskynet/p/14847526.html
备注:如果有需要Redis、以及Redis安装包的,以及安装教程,可以加以下的QQ群进行获取和咨询。
九、.net core(.NET 6)添加通用的Redis功能的更多相关文章
- 十二、.net core(.NET 6)添加通用的访问webapi的方法(包括HttpClient和HttpWebRequest)
开发通用的访问webapi方法. 在common工具文件夹下,新建一个类库项目:Wsk.Core.WebHelper,并引用Package包项目,然后新建一个类HttpClientHelper,用于使 ...
- 006.Adding a controller to a ASP.NET Core MVC app with Visual Studio -- 【在asp.net core mvc 中添加一个控制器】
Adding a controller to a ASP.NET Core MVC app with Visual Studio 在asp.net core mvc 中添加一个控制器 2017-2-2 ...
- 008.Adding a model to an ASP.NET Core MVC app --【在 asp.net core mvc 中添加一个model (模型)】
Adding a model to an ASP.NET Core MVC app在 asp.net core mvc 中添加一个model (模型)2017-3-30 8 分钟阅读时长 本文内容1. ...
- 007.Adding a view to an ASP.NET Core MVC app -- 【在asp.net core mvc中添加视图】
Adding a view to an ASP.NET Core MVC app 在asp.net core mvc中添加视图 2017-3-4 7 分钟阅读时长 本文内容 1.Changing vi ...
- 第六篇 ORACLE EBS用户界面通用元素或功能背后的道理解析
本篇打算介绍一下ORACLE EBS用户界面(User Interface)中通用的元素或功能背后蕴含的一些道理.这些通用元素或功能包括: List of Values (LOV),值列表 Flexf ...
- Redis in .NET Core 入门:(1) 安装和主要功能简介
Redis(https://redis.io/), 是一个内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 安装Redis 我很少在开发机中直接装各种数据库,我一般使用Docker,针对 ...
- 如何为 .NET Core CLI 启用 TAB 自动补全功能
如何为 .NET Core CLI 启用 TAB 自动补全功能 Intro 在 Linux 下经常可以发现有些目录/文件名,以及有些工具可以命令输入几个字母之后按 TAB 自动补全,最近发现其实 do ...
- 解析大型.NET ERP系统 通用附件管理功能
大型系统具备一个通用的附件管理功能,对于单据中无法清晰表达的字段,用一个附件图片或附件文档表示是最好的方法了.比如物料清单附加一张CAD图纸,销售订单评审功能中附加客户的各种表格,通用附件功能对系统起 ...
- 为现有图像处理程序添加读写exif的功能
为现有图像处理程序添加读取exif的功能 exif是图片的重要参数,在使用过程中很关键的一点是exif的数据能够和图片一起存在.exif的相关功能在操作系统中就集成了,在csharp中也似乎有了实现. ...
- FastReport 中添加二维码功能.(Delphi)
http://www.cnblogs.com/fancycloud/archive/2011/07/24/2115240.html FastReport 中添加二维码功能.(Delphi) 在实际 ...
随机推荐
- #二分图匹配#洛谷 5771 [JSOI2016]反质数序列
题目 给出 \(n\) 个正整数,问最大的子集使得任意两个数的和都不是质数 \(n\leq 3*10^3\) 分析 如果把两个数的和为质数连边,等价于求最大独立集. 由于只有偶数加奇数才可能产生质数( ...
- OpenHarmony持久化存储UI状态:PersistentStorage
前两个小节介绍的LocalStorage和AppStorage都是运行时的内存,但是在应用退出再次启动后,依然能保存选定的结果,是应用开发中十分常见的现象,这就需要用到PersistentStor ...
- XML 简介及用法详解
XML 是一种用于存储和传输数据的与软件和硬件无关的工具. 什么是XML? XML代表eXtensible Markup Language(可扩展标记语言).XML是一种与HTML非常相似的标记语言. ...
- 深入了解 Spring Boot 核心特性、注解和 Bean 作用域
Spring Boot 是什么? Spring Boot 是基于 Spring Framework 构建应用程序的框架,Spring Framework 是一个广泛使用的用于构建基于 Java 的企业 ...
- 异步、多线程、Java爬取某网站图片
一.网页图片爬取类 package com.yhyl.utils; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import or ...
- npm发包教程
1-npm注册账号 访问npm官网注册账号,邮件验证激活账号 npm官网 2-项目npm配置 在项目下打开终端,初始化npm npm init -y 此时项目下会生成package.json 配置文件 ...
- HDC2021技术分论坛:DevEco Testing,新增分布式测试功能
作者:lixiao,华为终端软件测试首席架构师:mindelong,华为终端软件测试工程师 HarmonyOS自诞生以来,致力于提供全场景智慧解决方案,打造分布式流转.多设备协同的分布式体验.全新解决 ...
- 【VMware vCenter】使用Reduced Downtime Update (RDU)升级更新vCenter Server。
Reduced Downtime Upgrade (RDU) 减少停机时间更新是用于vCenter Server更新升级的一种新的方式,顾名思义,主要目的就是为了减少在vCenter Server更新 ...
- 学Windows批处理第一天:使用批处理命令生成一个文件并写入内容
脚本功能:1.生成一个文件,文件名格式为:yyyymmddhhmmss 2.文件中写入一段文本 操作步骤:1.新建一个文本文档(txt格式) 2.修改文件名为任意名称(我的叫create_file), ...
- SVM简单分类的使用 sklearn机器学习
# sklearn 库中导入 svm 模块 from sklearn import svm # 定义三个点和标签 X = [[2, 0], [1, 1], [2,3]] y = [0, 0, 1] # ...