Asp.Net Core基于StackExchange Redis 缓存 - 教程
NuGet安装
StackExchange.Redis
Microsoft.Extensions.Options
0. appsettings.json初始化配置
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Redis": {
"ConnectionString": "localhost:6379",
"InstanceName": "anna_",
"DefaultDatabase": 5,
"ConnectRetry": 3,
"ConnectTimeout": 5000,
"AbortOnConnectFail": false
},
"ConnectionStrings": {
"default": "Host=10.10.11.185;Port=5432;Database=KSJGOM2DB;Username=postgres;Password=money13;"
}
}
1.Redis初始化对象
///
/// Redis初始化对象
///
public class RedisOptions
{
public const string Redis = "Redis";
public string ConnectionString { get; set; }
public string InstanceName { get; set; }
public int DefaultDatabase { get; set; } = 0;
public int ConnectRetry { get; set; } = 3;
public int ConnectTimeout { get; set; } = 5000;
public bool AbortOnConnectFail { get; set; } = false;
}
2.接口
public interface IRedisService
{
#region String 操作
Taskbool> StringSetAsyncT>(string key, T value, TimeSpan? expiry = null);
TaskT> StringGetAsyncT>(string key);
Tasklong> StringIncrementAsync(string key, long value = 1);
Tasklong> StringDecrementAsync(string key, long value = 1);
#endregion
#region Hash 操作
Taskbool> HashSetAsyncT>(string hashKey, string key, T value);
Taskbool> HashDeleteAsync(string hashKey, string key);
TaskT> HashGetAsyncT>(string hashKey, string key);
Taskstring, T>> HashGetAllAsync(string hashKey);
Tasklong> HashLengthAsync(string hashKey);
#endregion
#region List 操作
Tasklong> ListLeftPushAsyncT>(string key, T value);
Tasklong> ListRightPushAsyncT>(string key, T value);
TaskT> ListLeftPopAsyncT>(string key);
TaskT> ListRightPopAsyncT>(string key);
Tasklong> ListLengthAsync(string key);
Task> ListRangeAsync(string key, long start = 0, long stop = -1);
#endregion
#region Set 操作
Taskbool> SetAddAsyncT>(string key, T value);
Taskbool> SetRemoveAsyncT>(string key, T value);
Taskbool> SetContainsAsyncT>(string key, T value);
Tasklong> SetLengthAsync(string key);
Task> SetMembersAsync(string key);
#endregion
#region SortedSet 操作
Taskbool> SortedSetAddAsyncT>(string key, T value, double score);
Taskbool> SortedSetRemoveAsyncT>(string key, T value);
Taskdouble?> SortedSetScoreAsync(string key, T value);
Tasklong> SortedSetLengthAsync(string key);
Task> SortedSetRangeByRankAsync(string key, long start = 0, long stop = -1, Order order = Order.Ascending);
Task> SortedSetRangeByScoreAsync(string key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Order order = Order.Ascending);
#endregion
#region 通用操作
Taskbool> KeyDeleteAsync(string key);
Taskbool> KeyExistsAsync(string key);
Taskbool> KeyExpireAsync(string key, TimeSpan? expiry);
Task KeyTimeToLiveAsync(string key);
#endregion
}
3. 实现
public class RedisService : IRedisService, IDisposable
{
private readonly IConnectionMultiplexer _redis;
private readonly RedisOptions _options;
private readonly IDatabase _database;
private readonly JsonSerializerOptions _jsonOptions;
public RedisService(IOptions optionsAccessor)
{
_options = optionsAccessor.Value;
_jsonOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = false
};
var config = ConfigurationOptions.Parse(_options.ConnectionString);
config.AbortOnConnectFail = _options.AbortOnConnectFail;
config.ConnectRetry = _options.ConnectRetry;
config.ConnectTimeout = _options.ConnectTimeout;
_redis = ConnectionMultiplexer.Connect(config);
_database = _redis.GetDatabase(_options.DefaultDatabase);
}
private string GetPrefixedKey(string key) => $"{_options.InstanceName}{key}";
#region String 操作实现
public async Taskbool> StringSetAsyncT>(string key, T value, TimeSpan? expiry = null)
{
var json = JsonSerializer.Serialize(value, _jsonOptions);
return await _database.StringSetAsync(GetPrefixedKey(key), json, expiry);
}
public async TaskT> StringGetAsyncT>(string key)
{
var value = await _database.StringGetAsync(GetPrefixedKey(key));
return value.HasValue ? JsonSerializer.Deserialize(value, _jsonOptions) : default;
}
public async Tasklong> StringIncrementAsync(string key, long value = 1)
{
return await _database.StringIncrementAsync(GetPrefixedKey(key), value);
}
public async Tasklong> StringDecrementAsync(string key, long value = 1)
{
return await _database.StringDecrementAsync(GetPrefixedKey(key), value);
}
#endregion
#region Hash 操作实现
public async Taskbool> HashSetAsyncT>(string hashKey, string key, T value)
{
var json = JsonSerializer.Serialize(value, _jsonOptions);
return await _database.HashSetAsync(GetPrefixedKey(hashKey), key, json);
}
public async Taskbool> HashDeleteAsync(string hashKey, string key)
{
return await _database.HashDeleteAsync(GetPrefixedKey(hashKey), key);
}
public async TaskT> HashGetAsyncT>(string hashKey, string key)
{
var value = await _database.HashGetAsync(GetPrefixedKey(hashKey), key);
return value.HasValue ? JsonSerializer.Deserialize(value, _jsonOptions) : default;
}
public async TaskDictionarystring, T>> HashGetAllAsyncT>(string hashKey)
{
var entries = await _database.HashGetAllAsync(GetPrefixedKey(hashKey));
return entries.ToDictionary(
x => x.Name.ToString(),
x => JsonSerializer.Deserialize(x.Value, _jsonOptions));
}
public async Tasklong> HashLengthAsync(string hashKey)
{
return await _database.HashLengthAsync(GetPrefixedKey(hashKey));
}
#endregion
#region List 操作实现
public async Tasklong> ListLeftPushAsyncT>(string key, T value)
{
var json = JsonSerializer.Serialize(value, _jsonOptions);
return await _database.ListLeftPushAsync(GetPrefixedKey(key), json);
}
public async Tasklong> ListRightPushAsyncT>(string key, T value)
{
var json = JsonSerializer.Serialize(value, _jsonOptions);
return await _database.ListRightPushAsync(GetPrefixedKey(key), json);
}
public async TaskT> ListLeftPopAsyncT>(string key)
{
var value = await _database.ListLeftPopAsync(GetPrefixedKey(key));
return value.HasValue ? JsonSerializer.Deserialize(value, _jsonOptions) : default;
}
public async TaskT> ListRightPopAsyncT>(string key)
{
var value = await _database.ListRightPopAsync(GetPrefixedKey(key));
return value.HasValue ? JsonSerializer.Deserialize(value, _jsonOptions) : default;
}
public async Tasklong> ListLengthAsync(string key)
{
return await _database.ListLengthAsync(GetPrefixedKey(key));
}
public async TaskIEnumerableT>> ListRangeAsyncT>(string key, long start = 0, long stop = -1)
{
var values = await _database.ListRangeAsync(GetPrefixedKey(key), start, stop);
return values.Select(v => JsonSerializer.Deserialize(v, _jsonOptions));
}
#endregion
#region Set 操作实现
public async Taskbool> SetAddAsyncT>(string key, T value)
{
var json = JsonSerializer.Serialize(value, _jsonOptions);
return await _database.SetAddAsync(GetPrefixedKey(key), json);
}
public async Taskbool> SetRemoveAsyncT>(string key, T value)
{
var json = JsonSerializer.Serialize(value, _jsonOptions);
return await _database.SetRemoveAsync(GetPrefixedKey(key), json);
}
public async Taskbool> SetContainsAsyncT>(string key, T value)
{
var json = JsonSerializer.Serialize(value, _jsonOptions);
return await _database.SetContainsAsync(GetPrefixedKey(key), json);
}
public async Tasklong> SetLengthAsync(string key)
{
return await _database.SetLengthAsync(GetPrefixedKey(key));
}
public async TaskIEnumerableT>> SetMembersAsyncT>(string key)
{
var values = await _database.SetMembersAsync(GetPrefixedKey(key));
return values.Select(v => JsonSerializer.Deserialize(v, _jsonOptions));
}
#endregion
#region SortedSet 操作实现
public async Taskbool> SortedSetAddAsyncT>(string key, T value, double score)
{
var json = JsonSerializer.Serialize(value, _jsonOptions);
return await _database.SortedSetAddAsync(GetPrefixedKey(key), json, score);
}
public async Taskbool> SortedSetRemoveAsyncT>(string key, T value)
{
var json = JsonSerializer.Serialize(value, _jsonOptions);
return await _database.SortedSetRemoveAsync(GetPrefixedKey(key), json);
}
public async Taskdouble?> SortedSetScoreAsyncT>(string key, T value)
{
var json = JsonSerializer.Serialize(value, _jsonOptions);
return await _database.SortedSetScoreAsync(GetPrefixedKey(key), json);
}
public async Tasklong> SortedSetLengthAsync(string key)
{
return await _database.SortedSetLengthAsync(GetPrefixedKey(key));
}
public async TaskIEnumerableT>> SortedSetRangeByRankAsyncT>(string key, long start = 0, long stop = -1, Order order = Order.Ascending)
{
var values = await _database.SortedSetRangeByRankAsync(GetPrefixedKey(key), start, stop, order);
return values.Select(v => JsonSerializer.Deserialize(v, _jsonOptions));
}
public async TaskIEnumerableT>> SortedSetRangeByScoreAsyncT>(string key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Order order = Order.Ascending)
{
var values = await _database.SortedSetRangeByScoreAsync(GetPrefixedKey(key), start, stop, order: order);
return values.Select(v => JsonSerializer.Deserialize(v, _jsonOptions));
}
#endregion
#region 通用操作实现
public async Taskbool> KeyDeleteAsync(string key)
{
return await _database.KeyDeleteAsync(GetPrefixedKey(key));
}
public async Taskbool> KeyExistsAsync(string key)
{
return await _database.KeyExistsAsync(GetPrefixedKey(key));
}
public async Taskbool> KeyExpireAsync(string key, TimeSpan? expiry)
{
return await _database.KeyExpireAsync(GetPrefixedKey(key), expiry);
}
public async Task KeyTimeToLiveAsync(string key)
{
return await _database.KeyTimeToLiveAsync(GetPrefixedKey(key));
}
#endregion
public void Dispose()
{
_redis?.Dispose();
}
}
4.依赖注入
Program.cs中添加如下代码:
// 配置Redis选项
builder.Services.Configure(builder.Configuration.GetSection(RedisOptions.Redis));
// 注册Redis服务
builder.Services.AddSingleton();
5.控制器中使用
public class TestController : ControllerBase
{
private readonly IRedisService _redis;
private readonly IUserService _userService;
public TestController(IRedisService redis, IUserService userService)
{
_redis = redis;
_userService = userService;
}
[HttpGet("string")]
public async Task TestString()
{
var user = await _userService.GetCurrentUserAsync();
Console.WriteLine(user.TrueName);
await _redis.StringSetAsync("anna","多慢慢流");
var result = await _redis.StringGetAsyncstring>("anna");
return Ok(result);
}
[HttpGet("hash")]
public async Task TestHash()
{
string hkey = "fdm";
await _redis.HashSetAsync(hkey, "fd1",new {Name="annadeville",Props="运动型" });
await _redis.HashSetAsync(hkey,"fd2",new { Name="RR",Props="皮"});
var all= await _redis.HashGetAllAsyncdynamic>(hkey);
var fd1 = await _redis.HashGetAsyncdynamic>(hkey, "fd1");
return Ok(new { All = all, Field1 = fd1 });
}
}