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

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);
}

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

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) == )
{
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 > )
{
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) == )
{
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 ;
}
} 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 = ; 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 = ; 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客户端类实例:

private readonly IServiceStackRedisCache _cache;
public ValuesController(IServiceStackRedisCache cache)
{
_cache = cache;
}

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

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

asp.net core 上使用redis探索(3)--redis示例demo的更多相关文章

  1. asp.net core上使用Redis探索(2)

    在<<asp.net core上使用Redis探索(1)>>中,我介绍了一个微软官方实现Microsoft.Extensions.Caching.Redis的类库,这次,我们使 ...

  2. 使用Code First建模自引用关系笔记 asp.net core上使用redis探索(1) asp.net mvc控制器激活全分析 语言入门必学的基础知识你还记得么? 反射

    使用Code First建模自引用关系笔记   原文链接 一.Has方法: A.HasRequired(a => a.B); HasOptional:前者包含后者一个实例或者为null HasR ...

  3. asp.net core上使用Redis demo

    整体思路:(1.面向接口编程 2.Redis可视化操作IDE 3.Redis服务) [无私分享:ASP.NET CORE 项目实战(第十一章)]Asp.net Core 缓存 MemoryCache ...

  4. Asp.Net Core Web应用程序—探索

    前言 作为一个Windows系统下的开发者,我对于Core的使用机会几乎为0,但是考虑到微软的战略规划,我觉得,Core还是有先了解起来的必要. 因为,目前微软已经搞出了两个框架了,一个是Net标准( ...

  5. 在ASP.NET Core上实施每个租户策略的数据库

    在ASP.NET Core上实施每个租户策略的数据库 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: http://g ...

  6. Angular 2的HTML5 pushState在ASP.NET Core上的解决思路

    Angular 2的HTML5 pushState在ASP.NET Core上的解决思路 正如Angular 2在Routing & Navigation中所提及的那样,Angular 2是推 ...

  7. Asp.Net Core基于JWT认证的数据接口网关Demo

    近日,应一位朋友的邀请写了个Asp.Net Core基于JWT认证的数据接口网关Demo.朋友自己开了个公司,接到的一个升级项目,客户要求用Aps.Net Core做数据网关服务且基于JWT认证实现对 ...

  8. asp.net core系列 39 Razor 介绍与详细示例

    原文:asp.net core系列 39 Razor 介绍与详细示例 一. Razor介绍 在使用ASP.NET Core Web开发时, ASP.NET Core MVC 提供了一个新特性Razor ...

  9. asp.net core上使用redis探索(1)

    基于Ubuntu安装redis, 我找的一个很好的网站: https://www.digitalocean.com/community/tutorials/how-to-install-and-con ...

  10. 第十二节:Asp.Net Core 之分布式缓存(SQLServer和Redis)

    一. 整体说明 1. 说明 分布式缓存通常是指在多个应用程序服务器的架构下,作为他们共享的外部服务共享缓存,常用的有SQLServer.Redis.NCache.     特别说明一下:这里的分布式是 ...

随机推荐

  1. Eclipse搭建.C#和..NET Core环境

    1.在上一篇博客中我介绍了如何使用Eclipse搭建C++.C开发环境,顺带把搭建 .NET Core 和C#也做个介绍.配置任何环境关键是找到要开发语言的编辑器和SDK.eclipse是java开发 ...

  2. 大明A+B

    大明A+B 时间限制: 1 Sec  内存限制: 32 MB 以内加法的那个"小明"了,现在他甚至会任意长度的正小数的加法.现在,给你两个正的小数A和B,你的任务是代表大明计算出A ...

  3. APIView源码分析

    什么是REST REST与技术无关,代表的是一种软件架构风格.REST全称是Representational State Tranfer, 表征性状态转移. REST从资源的角度类审视整个网络,它将分 ...

  4. 查看mysql 默认端口号和修改端口号

    1. 登录mysql mysql -u root -p //输入密码 2. 使用命令show global variables like 'port';查看端口号 mysql> show glo ...

  5. Mac下Java JDK的下载安装和配置

    一.下载安装 打开一个搜索引擎,输入JDK,找到Java JDK 如图:  点击打开,同意协议开始下载如图: 下载好以后,安装即可. 安装成功以后,进入根目录,可以找到JDK安装的位置: 资源库——& ...

  6. XMind思维导图使用笔记

    首先新建一个空白的图 以组织结构图(向下)  为例 1.双击组织结构图 创建一个空白的页面 2.随便选择一个风格 这时候出现工作台 现在里面只有一个中心主题 正文部分开始 1.如果想要添加一个子主题 ...

  7. 集腋成裘-01 sublime常用的快捷键

    sublime使用的快捷键 1:Html 结构代码  : Html:xt + tab键 2:补全标签代码   : tab键 3:快速复制一行代码 : Ctrl+shift+d 4:快速选中一行代码 : ...

  8. oa项目环境搭建的操作步骤详解

    dto:多表关联查询用单独建一个类,把查询数据放dto即可 vo:是view的缩写.单独定义一个类

  9. Linux桌面环境安装matlab并创建快捷方式

    安装matlab sudo mkdir -p /mnt/matlab sudo mount -t auto -o loop /home/chris/Downloads/2016b_linux/R201 ...

  10. 如何让微信里的html应用弹出“点击右上角分享到朋友圈”的图片

    一个分享按钮,一个隐藏的图片(这个图片绝对定位在右上角)然后就是点击显示,点击隐藏了... <a href="javascript:;" onclick="docu ...