Skip to content

Instantly share code, notes, and snippets.

@kwal
Created August 13, 2015 15:03
Show Gist options
  • Save kwal/4472b1355f104b86e344 to your computer and use it in GitHub Desktop.
Save kwal/4472b1355f104b86e344 to your computer and use it in GitHub Desktop.
Redis Cache
using Newtonsoft.Json;
using NLog;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
public class RedisCache : ICache
{
private readonly IConfiguration _config;
private readonly ILogger _logger;
private readonly IConnectionMultiplexer _redis;
public RedisCache(
IConfiguration config,
ILogger logger,
IConnectionMultiplexer connection)
{
_config = config;
_logger = logger;
_redis = connection;
}
public T GetOrAdd<T>(string key, Func<T> expression, TimeSpan? expiration = null) where T : class
{
if (expression == null)
{
throw new ArgumentNullException("expression");
}
IDatabase db = null;
var fullKey = BuildFullKey<T>(key);
if (_redis.IsConnected)
{
try
{
db = _redis.GetDatabase();
var cacheResult = db.StringGet(fullKey);
if (cacheResult.HasValue)
{
return JsonConvert.DeserializeObject<T>(cacheResult);
}
}
catch (TimeoutException ex)
{
_logger.Warn(ex);
}
}
T result = expression();
if (db != null && result != null)
{
db.StringSet(fullKey, JsonConvert.SerializeObject(result), expiration, flags: CommandFlags.FireAndForget);
}
return result;
}
public IEnumerable<T> GetOrAdd<T>(string key, Func<IEnumerable<T>> expression, TimeSpan? expiration = null) where T : class
{
if (expression == null)
{
throw new ArgumentNullException("expression");
}
IDatabase db = null;
var fullKey = BuildFullKey<T>(key);
if (_redis.IsConnected)
{
try
{
db = _redis.GetDatabase();
if (db.KeyExists(fullKey))
{
var cacheResult = db.SetMembers(fullKey);
if (cacheResult != null)
{
return cacheResult.Select(x => JsonConvert.DeserializeObject<T>(x)).ToList();
}
}
}
catch (TimeoutException ex)
{
_logger.Warn(ex);
}
}
IEnumerable<T> results = expression();
if (db != null && results != null)
{
var values = results.Select(x => (RedisValue)JsonConvert.SerializeObject(x)).ToArray();
db.SetAdd(fullKey, values, flags: CommandFlags.FireAndForget);
db.KeyExpire(fullKey, expiration, flags: CommandFlags.FireAndForget);
}
return results;
}
public void AddOrUpdate<T>(string key, T value, TimeSpan? expiration = null) where T : class
{
if (String.IsNullOrWhiteSpace(key))
{
throw new ArgumentException("Must be non-empty", "key");
}
if (value == null)
{
throw new ArgumentNullException("value");
}
IDatabase db = null;
var fullKey = BuildFullKey<T>(key);
if (_redis.IsConnected)
{
try
{
db = _redis.GetDatabase();
db.StringSet(fullKey, JsonConvert.SerializeObject(value), expiration);
}
catch (TimeoutException ex)
{
_logger.Warn(ex);
}
}
}
public void Remove<T>(string key) where T : class
{
if (String.IsNullOrWhiteSpace(key))
{
throw new ArgumentException("Must be non-empty", "key");
}
IDatabase db = null;
var fullKey = BuildFullKey<T>(key);
if (_redis.IsConnected)
{
try
{
db = _redis.GetDatabase();
db.KeyDelete(fullKey);
}
catch (TimeoutException ex)
{
_logger.Warn(ex);
}
}
}
private string BuildFullKey<T>(string key)
{
return String.Format("{0}:{1}:{2}", _config.CachePrefix, typeof(T).Name, key);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment