.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功能的更多相关文章

  1. 十二、.net core(.NET 6)添加通用的访问webapi的方法(包括HttpClient和HttpWebRequest)

    开发通用的访问webapi方法. 在common工具文件夹下,新建一个类库项目:Wsk.Core.WebHelper,并引用Package包项目,然后新建一个类HttpClientHelper,用于使 ...

  2. 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 ...

  3. 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. ...

  4. 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 ...

  5. 第六篇 ORACLE EBS用户界面通用元素或功能背后的道理解析

    本篇打算介绍一下ORACLE EBS用户界面(User Interface)中通用的元素或功能背后蕴含的一些道理.这些通用元素或功能包括: List of Values (LOV),值列表 Flexf ...

  6. Redis in .NET Core 入门:(1) 安装和主要功能简介

    Redis(https://redis.io/), 是一个内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 安装Redis 我很少在开发机中直接装各种数据库,我一般使用Docker,针对 ...

  7. 如何为 .NET Core CLI 启用 TAB 自动补全功能

    如何为 .NET Core CLI 启用 TAB 自动补全功能 Intro 在 Linux 下经常可以发现有些目录/文件名,以及有些工具可以命令输入几个字母之后按 TAB 自动补全,最近发现其实 do ...

  8. 解析大型.NET ERP系统 通用附件管理功能

    大型系统具备一个通用的附件管理功能,对于单据中无法清晰表达的字段,用一个附件图片或附件文档表示是最好的方法了.比如物料清单附加一张CAD图纸,销售订单评审功能中附加客户的各种表格,通用附件功能对系统起 ...

  9. 为现有图像处理程序添加读写exif的功能

    为现有图像处理程序添加读取exif的功能 exif是图片的重要参数,在使用过程中很关键的一点是exif的数据能够和图片一起存在.exif的相关功能在操作系统中就集成了,在csharp中也似乎有了实现. ...

  10. FastReport 中添加二维码功能.(Delphi)

    http://www.cnblogs.com/fancycloud/archive/2011/07/24/2115240.html FastReport 中添加二维码功能.(Delphi)   在实际 ...

随机推荐

  1. 【直播回顾】OpenHarmony知识赋能第五期第二课——如何成为社区贡献达人

    4月28日晚上19点,知识赋能第五期第二节课<如何成为OpenHarmony社区贡献达人?>,在OpenHarmony开发者成长计划社群内成功举行. 本期课程,由华为社区运营专家祝尚元主讲 ...

  2. 4. Orthogonality

    4.1 Orthogonal Vectors and Suspaces Orthogonal vectors have \(v^Tw=0\),and \(||v||^2 + ||w||^2 = ||v ...

  3. Qt:获取WIFI列表

    示例:使用QT来获取Windows电脑WIFI列表中所有WIFI的名称,实际是执行CMD命令来完成(netsh wlan show networks) // 获取WIFI列表 QProcess pro ...

  4. chatGPT教你学sql的事务

    事务的隔离级别 事务的隔离级别是指多个并发事务之间相互隔离的程度,主要是为了解决并发事务带来的一致性问题,它的主要作用是控制数据库中事务的可见性和可重复读. 在 SQL 标准中,定义了四种事务隔离级别 ...

  5. HarmonyOS Codelab 优秀样例——溪村小镇(ArkTS)

    一.  介绍 溪村小镇是一款展示溪流背坡村园区风貌的应用,包括园区内的导航功能,小火车行车状态查看,以及各区域的风景展览介绍,主要用于展示HarmonyOS的ArkUI能力和动画效果.具体包括如下功能 ...

  6. HDC2021技术分论坛:DevEco Testing,新增分布式测试功能

    作者:lixiao,华为终端软件测试首席架构师:mindelong,华为终端软件测试工程师 HarmonyOS自诞生以来,致力于提供全场景智慧解决方案,打造分布式流转.多设备协同的分布式体验.全新解决 ...

  7. 重新整理.net core 计1400篇[九] (.net core 中的依赖注入的服务注入)

    前言 在该系列六中介绍了一个简单的依赖注入,该节介绍.net core 中的依赖注入的服务注入. ServiceDescriptor ServiceDescriptor 是服务描述的意思,这个是做什么 ...

  8. 《c#高级编程》第4章C#4.0中的更改(六)——动态绑定

    一.概念 下面是一些代码示例,说明C#动态绑定的上述特点: 1. 延迟确定类型 ```dynamic obj = GetDynamicObject(); // 获取动态对象obj.DoSomethin ...

  9. 【SQL】将日期时间转换成年月日的日期形式

    [SQL]将日期时间转换成年月日的日期形式 这段时间写力扣的SQL题,发现了各式各样的转换时间的方法,正好记录一下 TO_CHAR(XXX,'YYYY-MM-DD') 这个在Oracle应该是很常用的 ...

  10. 成本节省 50%,9人团队使用函数计算开发 wolai 在线文档应用

    简介: 通过使用函数计算,wolai 的前端工程师们就可以把从前到后的一整套开发流程负责起来,我们的研发迭代速度非常快.   ​ 作者| 马锐拉(wolai.com 创始人) 我们的日常工作场景几乎离 ...