由于是基于.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. Python实战一

    要求:用户输入用户名和密码错误三次,就对该用户进行锁定,不让其进行登录. def match(name,pwd): '''匹配用户输入的信息,进行判断''' falg = True while fal ...

  2. MySQL监控系统Lepus的搭建

    现在流行的监控系统很多,选择一个合适自己的就可以了,例如Zabbix.Nagios:监控MySQL为主的有MySQLMTOP.Lepus.本文主要介绍快速部署lepus以及监控MySQL,因为作为DB ...

  3. window下tomcat的内存溢出问题

    打开注册表:https://jingyan.baidu.com/article/49ad8bce09d6085835d8fa63.html Tomcat 内存溢出对应解决方式 Windows平台,使用 ...

  4. js 浮点数相加 变成字符串 解决方案

    var count = 0; count+=Number(parseFloat(value[i]['sla']).toFixed(2)); 数字相加的时候最好使用Number转换一下

  5. Python函数之内置函数

    截止导Python 3.6 目前内置函数有68个 以下是对这些内置函数的分类 一:作用域相关 以字典的形式返回作用域中的名字 locals # 返回本地作用域的所有名字 globals # 返回全局作 ...

  6. OpenCV-Python入门教程1-图片

    首先感觉学习OpenCV-python最好的学习工具官方的英文文档. 官方英文教程:OpenCV-Python Tutorials 我使用的是anaconda里的 jupyter notebook.至 ...

  7. Python sendmail

    #coding:utf- #强制使用utf-8编码格式 import smtplib #加载smtplib模块 from email.mime.text import MIMEText from em ...

  8. sqlserver数据库不能重命名报错5030

    在学习asp.net的时候使用mssql'经常会出现这种错误,数据库不能重名名5030的错误,其实很简单原因就是有应用程序正在占用这个连接,使用这样一行命令就可以查询出正在占用的连接 use mast ...

  9. 期货大赛项目|四,MVC的数据验证

    上图先看下效果 样式先不说,先了解下数据验证是怎么实现的 一 必须是强类型的视图 二 这些显示提示的话语,都在强类型的实体中 三 必须使用Html.BeginForm或者Html.AjaxBeginF ...

  10. 洛谷---小L和小K的NOIP考后放松赛

    链接: https://www.luogu.org/contestnew/show/11805?tdsourcetag=s_pcqq_aiomsg 题解: 没人过的题我就没看 t2: 考虑每个点是朋友 ...