研究了下redis在.net下的使用,因为以前在java上用redis用的是jedis操作,在.net不是很熟悉,在网站上也看了一部分的.net下redis的使用,大部分都是ServiceStack.Redis听说ServiceStack.Redis4.0版本都是收费的,这个我不是很清楚,但是我确实有项目再用ServiceStack.Redis。

这里就不讨论ServiceStack.Redis的使用今天带来的是StackExchange.Redis的封装版。

代码参考

DDD领域驱动之干货(三)完结篇!

下面是干货

RedisCaching里面放着的是Redis的基本5个方法分别如下图所示:

RedisCommon里面放着的是redis的帮助类和初始化类如下图所示:

现在举了例子就以DoRedisStringCache为例:

实现了接口IRedisCaching,当然这里这个接口是标识接口意思就是用来约束的。

StackExchange.Redis是初始化是单列模式,内部有一套自己的方法,这里我就放一下代码

这里面还有6个事件如下图:

代码贴出来:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;
using KuRuMi.Mio.DoMain.Infrastructure.Logger; namespace KuRuMi.Mio.DoMain.RedisCache.RedisCommon
{
public class RedisManager
{
private static string Constring = RedisConfig.Config();
private static readonly object locker = new object();
private static ConnectionMultiplexer instance;
private static readonly Dictionary<string, ConnectionMultiplexer> Concache = new Dictionary<string, ConnectionMultiplexer>(); /// <summary>
/// 单例模式获取redis连接实例
/// </summary>
public static ConnectionMultiplexer Instance
{
get
{
if (instance == null)
{
lock (locker)
{
if (instance == null)
instance = GetManager();
}
}
return instance;
}
} /// <summary>
/// 从缓存中获取
/// </summary>
/// <param name="constr"></param>
/// <returns></returns>
public static ConnectionMultiplexer GetConForMap(string constr) {
if (!Concache.ContainsKey(constr))
Concache[constr] = GetManager(constr);
return Concache[constr];
} private static ConnectionMultiplexer GetManager(string constr = null)
{
constr = constr ?? Constring;
var connect = ConnectionMultiplexer.Connect(constr); #region 注册事件
connect.ConnectionFailed += MuxerConnectionFailed;
connect.ConnectionRestored += MuxerConnectionRestored;
connect.ErrorMessage += MuxerErrorMessage;
connect.ConfigurationChanged += MuxerConfigurationChanged;
connect.HashSlotMoved += MuxerHashSlotMoved;
connect.InternalError += MuxerInternalError;
#endregion return connect;
}
#region Redis事件
/// <summary>
/// 内部异常
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerInternalError(object sender, InternalErrorEventArgs e)
{
Units.Log("内部异常:" + e.Exception.Message);
} /// <summary>
/// 集群更改
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)
{
Units.Log("新集群:" + e.NewEndPoint + "旧集群:" + e.OldEndPoint);
} /// <summary>
/// 配置更改事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e)
{
Units.Log("配置更改:" + e.EndPoint);
} /// <summary>
/// 错误事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)
{
Units.Log("异常信息:" + e.Message);
} /// <summary>
/// 重连错误事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)
{
Units.Log("重连错误" + e.EndPoint);
} /// <summary>
/// 连接失败事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)
{
Units.Log("连接异常" + e.EndPoint + ",类型为" + e.FailureType + (e.Exception == null ? "" : (",异常信息是" + e.Exception.Message)));
}
#endregion
}
}

下面是redis的config:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace KuRuMi.Mio.DoMain.RedisCache.RedisCommon
{
public sealed class RedisConfig
{
public static readonly string config = ConfigurationManager.AppSettings["RedisConfig"];
public static readonly string redisKey = ConfigurationManager.AppSettings["RedisKey"] ?? "";
public static string Config() {
return config;
}
public static string Key() {
return redisKey;
}
}
}

下面是redis的helper:

using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace KuRuMi.Mio.DoMain.RedisCache.RedisCommon
{
public class RedisBase
{
private static ConnectionMultiplexer db = null;
private static string key = string.Empty; private int DbNumber { get; }
public RedisBase(int dbnum = 0) : this(dbnum, null)
{ } public RedisBase(int dbnum, string connectionString)
{
DbNumber = dbnum;
db = string.IsNullOrWhiteSpace(connectionString) ? RedisManager.Instance : RedisManager.GetConForMap(connectionString);
} #region 辅助方法
/// <summary>
/// 添加名称
/// </summary>
/// <param name="old"></param>
/// <returns></returns>
public string AddKey(string old)
{
var fixkey = key ?? RedisConfig.Key();
return fixkey + old;
} /// <summary>
/// 执行保存
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func"></param>
/// <returns></returns>
public T DoSave<T>(Func<IDatabase, T> func)
{
return func(db.GetDatabase(DbNumber));
}
public string ConvertJson<T>(T val)
{
return val is string ? val.ToString() : JsonConvert.SerializeObject(val);
} public T ConvertObj<T>(RedisValue val)
{
return JsonConvert.DeserializeObject<T>(val);
} public List<T> ConvertList<T>(RedisValue[] val)
{
List<T> result = new List<T>();
foreach (var item in val)
{
var model = ConvertObj<T>(item);
result.Add(model);
}
return result;
} public RedisKey[] ConvertRedisKeys(List<string> val)
{
return val.Select(k => (RedisKey)k).ToArray();
}
#endregion
}
}

下面是我的string封装方法:

using KuRuMi.Mio.DoMain.RedisCache.RedisCommon;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace KuRuMi.Mio.DoMain.RedisCache.RedisCaching
{
/// <summary>
/// 表示string的操作
/// </summary>
public class DoRedisStringCache : IRedisCaching
{
private RedisBase redis = null;
public DoRedisStringCache()
{
redis = new RedisBase();
} #region 同步执行
/// <summary>
/// 单个保存
/// </summary>
/// <param name="key"></param>
/// <param name="val">值</param>
/// <param name="exp">过期时间</param>
/// <returns></returns>
public bool StringSet(string key, string val, TimeSpan? exp = default(TimeSpan?))
{
key = redis.AddKey(key);
return redis.DoSave(db => db.StringSet(key, val, exp));
} /// <summary>
/// 保存多个key value
/// </summary>
/// <param name="keyValues">键值对</param>
/// <returns></returns>
public bool StringSet(List<KeyValuePair<RedisKey, RedisValue>> KeyVal)
{
List<KeyValuePair<RedisKey, RedisValue>> newkey = KeyVal.Select(k => new KeyValuePair<RedisKey, RedisValue>(redis.AddKey(k.Key), k.Value)).ToList();
return redis.DoSave(db => db.StringSet(newkey.ToArray()));
} /// <summary>
/// 保存一个对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="obj"></param>
/// <param name="exp"></param>
/// <returns></returns>
public bool StringSet<T>(string key, T obj, TimeSpan? exp = default(TimeSpan?))
{
key = redis.AddKey(key);
string json = redis.ConvertJson(obj);
return redis.DoSave(db => db.StringSet(key, json, exp));
} /// <summary>
/// 获取单个
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string StringGet(string key)
{
key = redis.AddKey(key);
return redis.DoSave(db => db.StringGet(key));
}
/// <summary>
/// 获取单个对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public T StringGet<T>(string key) {
key = redis.AddKey(key);
var val = redis.DoSave(db => db.StringGet(key));
return redis.ConvertObj<T>(val);
} /// <summary>
/// 为数字增长val
/// </summary>
/// <param name="key"></param>
/// <param name="val">可以为负数</param>
/// <returns>增长后的值</returns>
public double StringIncrement(string key, double val = 1)
{
key = redis.AddKey(key);
return redis.DoSave(db => db.StringIncrement(key, val));
}
/// <summary>
/// 为数字减少val
/// </summary>
/// <param name="key"></param>
/// <param name="val">可以为负数</param>
/// <returns>增长后的值</returns>
public double StringDecrement(string key, double val = 1)
{
key = redis.AddKey(key);
return redis.DoSave(db => db.StringDecrement(key, val));
}
#endregion #region 异步执行
/// <summary>
/// 异步保存单个
/// </summary>
/// <param name="key"></param>
/// <param name="val"></param>
/// <param name="exp"></param>
/// <returns></returns>
public async Task<bool> StringSetAsync(string key, string val, TimeSpan? exp = default(TimeSpan?))
{
key = redis.AddKey(key);
return await redis.DoSave(db => db.StringSetAsync(key, val, exp));
}
/// <summary>
/// 异步保存多个key value
/// </summary>
/// <param name="keyValues">键值对</param>
/// <returns></returns>
public async Task<bool> StringSetAsync(List<KeyValuePair<RedisKey, RedisValue>> KeyVal)
{
List<KeyValuePair<RedisKey, RedisValue>> newkey = KeyVal.Select(k => new KeyValuePair<RedisKey, RedisValue>(redis.AddKey(k.Key), k.Value)).ToList();
return await redis.DoSave(db => db.StringSetAsync(newkey.ToArray()));
} /// <summary>
/// 异步保存一个对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="obj"></param>
/// <param name="exp"></param>
/// <returns></returns>
public async Task<bool> StringSetAsync<T>(string key, T obj, TimeSpan? exp = default(TimeSpan?))
{
key = redis.AddKey(key);
string json = redis.ConvertJson(obj);
return await redis.DoSave(db => db.StringSetAsync(key, json, exp));
} /// <summary>
/// 异步获取单个
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<string> StringGetAsync(string key)
{
key = redis.AddKey(key);
return await redis.DoSave(db => db.StringGetAsync(key));
} /// <summary>
/// 异步获取单个
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<T> StringGetAsync<T>(string key)
{
key = redis.AddKey(key);
var val = await redis.DoSave(db => db.StringGetAsync(key));
return redis.ConvertObj<T>(val);
} /// <summary>
/// 异步为数字增长val
/// </summary>
/// <param name="key"></param>
/// <param name="val">可以为负数</param>
/// <returns>增长后的值</returns>
public async Task<double> StringIncrementAsync(string key, double val = 1)
{
key = redis.AddKey(key);
return await redis.DoSave(db => db.StringIncrementAsync(key, val));
}
/// <summary>
/// 为数字减少val
/// </summary>
/// <param name="key"></param>
/// <param name="val">可以为负数</param>
/// <returns>增长后的值</returns>
public async Task<double> StringDecrementAsync(string key, double val = 1)
{
key = redis.AddKey(key);
return await redis.DoSave(db => db.StringDecrementAsync(key, val));
}
#endregion
}
}

StackExchange.Redis本身提供了一套异步的方法这个我比较喜欢。至于其他的和string的同理,我这里就不放出封装方法,需要的留言。

最后是测试:

这是我的redis然后是我的数据库

这里是我登录的测试代码:

在.Net下使用redis基于StackExchange.Redis--登录功能的更多相关文章

  1. 在.Net下使用redis基于StackExchange.Redis

    研究了下redis在.net下的使用,因为以前在java上用redis用的是jedis操作,在.net不是很熟悉,在网站上也看了一部分的.net下redis的使用,大部分都是ServiceStack. ...

  2. .net core 使用redis 基于 StackExchange.Redis

    一.添加引用包 StackExchange.Redis Microsoft.Extensions.Configuration   二.修改配置文件 appsettings.json   { " ...

  3. 『性能』ServiceStack.Redis 和 StackExchange.Redis 性能比较

    背景 近来,需要用到 Redis 这类缓存技术 —— MongoDB 和 Redis 没有进行过比较. 我也懒得在这些细节上 纠结那么多 —— 按照网友给出的文章,听从网友建议,选择 Redis. R ...

  4. (三)Redis for StackExchange.Redis

    目录 (一)Redis for Windows正确打开方式 (二)Redis for 阿里云公网连接 (三)Redis for StackExchange.Redis StackExchange.Re ...

  5. asp.net Core 使用redis(StackExchange.Redis)

    原文:asp.net Core 使用redis(StackExchange.Redis) 一.添加配置(appsettings.json) "Redis": { "Def ...

  6. [Open Source] .NET 基于StackExchange.Redis的扩展

    目录 简介 主从复制 备份与恢复 API AddOrUpdate GetOrAdd DeleteByPattern SearchKeys TransExcute Subscribe/Publish T ...

  7. 怎样在Redis通过StackExchange.Redis 存储集合类型List

    StackExchange 是由StackOverFlow出品, 是对Redis的.NET封装,被越来越多的.NET开发者使用在项目中. 绝大部分原先使用ServiceStack的开发者逐渐都转了过来 ...

  8. .NetCore使用Redis,StackExchange.Redis队列,发布与订阅,分布式锁的简单使用

    环境:之前一直是使用serverStack.Redis的客服端,今天来使用一下StackExchange.Redis(个人感觉更加的人性化一些,也是免费的,性能也不会差太多),版本为StackExch ...

  9. 在.net中使用redis(StackExchange.Redis)

    本文介绍如何在.net中使用redis 安装 代码使用 StackExchange.Redis基础使用 StackExchange.Redis中的事务 安装(windows平台) 安装Chocolat ...

随机推荐

  1. R语言(一)

    向量运算 R的强大功能之一就是把整个数据向量作为一个单一对象来处理.一个数据向量仅是数字的排列,一个向量可以通过如下方式构造 weight<-c(,,,) weight [] 结构c(--)用来 ...

  2. 判断数A和数B中有多少个位不相同

    1. A & B,得到的结果C中的1的位表明了A和B中相同的位都是1的位:2. A | B, 得到的结果D中的1的位表明了A和B在该位至少有一个为1的位,包含了A 与 B 都是1的位数,经过前 ...

  3. 小计---pandas读取带有中文文件名或者包含中文内容的文件

    python2下: # -*- coding: utf-8 -*- import pandas as pd mydata = pd.read_csv(u"例子.csv") #前面加 ...

  4. Get Region Information from IP Address with Taobao API

    通过淘宝的API "http://ip.taobao.com/service/getIpInfo.php?ip=*.*.*.*" 来获得你要查询的IP地址的国家,地区,城市,ISP ...

  5. 2015/7/29 (高开,V形反转,各种指标背离——可惜没买进,填补空缺图形的心理分析)

    1.李大--謝先生℡:早盘决策:如今日再次出现大幅低开  或者盘中大幅下跌可逢低 3成仓位左右分散资金做短线抄底,切记是超短 绝不追高,设置5个点止损.市场有很多名家在谈论3373点即前低点,本人告诉 ...

  6. 工作了3年的JAVA程序员应该具备什么技能?(转)

    工作了3年的JAVA程序员应该具备什么技能? 因为和同事有约定再加上LZ自己也喜欢做完一件事之后进行总结,因此有了这篇文章.这篇文章大部分内容都是面向整个程序员群体的,当然因为LZ本身是做Java开发 ...

  7. 正则表达式 获取字符串内提取图片URL字符串

    #region 获取字符串内提取图片URL字符串 /// <summary> /// 获取字符串内提取图片URL字符串 /// </summary> /// <param ...

  8. curl扩展代码

    /** * * curl 支持post * @param string $base_url 基础链接 * @param array $query_data 需要请求的数据 * @param strin ...

  9. Swift中的? ! as as? as!

    ?: 代表这是个可选类型(optional)的.如下,如果num有就为Int类型的,如果没有值那么就是nil. let num:Int? 当我对number进行显示赋值时那么number就是Int类型 ...

  10. Python的文件读写与存储

    文件读写与存储 7.2. 读写文件 open()返回一个文件对象,最常见的用法带有两个参数:open(filename, mode). >>> f = open('workfile' ...