using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Threading.Tasks; namespace Roadie.Library.Caching { /// /// Redis Cache implemention /// /// public class RedisCacheManager : CacheManagerBase { private static Lazy lazyConnection = new Lazy(() => { return ConnectionMultiplexer.Connect("192.168.1.253:6379,allowAdmin=true"); }); private bool _doTraceLogging = true; private IDatabase _redis = null; public static ConnectionMultiplexer Connection { get { return lazyConnection.Value; } } private IDatabase Redis { get { return this._redis ?? (this._redis = Connection.GetDatabase()); } } public RedisCacheManager(ILogger logger, CachePolicy defaultPolicy) : base(logger, defaultPolicy) { } public override bool Add(string key, TCacheValue value) { return this.Add(key, value, null, this._defaultPolicy); } public override bool Add(string key, TCacheValue value, string region) { return this.Add(key, value, region, null); } public override bool Add(string key, TCacheValue value, CachePolicy policy) { return this.Add(key, value, null, this._defaultPolicy); } public override bool Add(string key, TCacheValue value, string region, CachePolicy policy) { if (this._doTraceLogging) { this.Logger.LogTrace("Added [{0}], Region [{1}]", key, region); } return this.Redis.StringSet(key, this.Serialize(value)); } public override void Clear() { var endpoints = Connection.GetEndPoints(); var server = Connection.GetServer(endpoints[0]); server.FlushAllDatabases(); if (this._doTraceLogging) { this.Logger.LogTrace("Cleared Cache"); } } public override void ClearRegion(string region) { this.Clear(); } public override bool Exists(string key) { return this.Exists(key, null); } public override bool Exists(string key, string region) { return this.Redis.KeyExists(key); } public override TOut Get(string key) { return this.Get(key, null); } public override TOut Get(string key, string region) { return this.Get(key, region, this._defaultPolicy); } public override TOut Get(string key, Func getItem, string region) { return this.Get(key, getItem, region, this._defaultPolicy); } public override TOut Get(string key, Func getItem, string region, CachePolicy policy) { var r = this.Get(key, region); if (r == null) { r = getItem(); this.Add(key, r, region, policy); } return r; } public override bool Remove(string key) { return this.Remove(key, null); } public override bool Remove(string key, string region) { if (this.Redis.KeyExists(key)) { this.Redis.KeyDelete(key); } return false; } protected virtual void Dispose(bool disposing) { if (disposing) { try { Connection.Close(); Connection.Dispose(); } catch { } } // free native resources here if there are any } private TOut Get(string key, string region, CachePolicy policy) { var result = this.Deserialize(this.Redis.StringGet(key)); if (result == null) { if (this._doTraceLogging) { this.Logger.LogTrace("Get Cache Miss Key [{0}], Region [{1}]", key, region); } } else if (this._doTraceLogging) { this.Logger.LogTrace("Get Cache Hit Key [{0}], Region [{1}]", key, region); } return result; } public override Task GetAsync(string key, Func> getItem, string region) { throw new NotImplementedException(); } } internal class IgnoreJsonAttributesResolver : DefaultContractResolver { protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) { IList props = base.CreateProperties(type, memberSerialization); foreach (var prop in props) { prop.Ignored = false; // Ignore [JsonIgnore] prop.Converter = null; // Ignore [JsonConverter] prop.PropertyName = prop.UnderlyingName; // restore original property name } return props; } } }