private static string GetCacheKey <T>(Tag.Name tag, T returnType, object parameters = null)
        {
            string _tag           = tag.ToString();
            string returnTypeName = typeof(T).AssemblyQualifiedName;
            string _parameters    = string.Empty;

            if (parameters != null)
            {
                _parameters = Newtonsoft.Json.JsonConvert.SerializeObject(parameters);
            }
            return(SHA256(string.Format("{0}_{1}_{2}", _tag, returnTypeName, _parameters)));
        }
        public async static Task RemoveAsync <T>(this IDistributedCache distributedCache, Tag.Name tag, object parameters, CancellationToken token = default)
        {
            T      value    = default;
            string cacheKey = GetCacheKey(tag, value, parameters);
            await distributedCache.RemoveAsync(cacheKey, token);

            await RemoveHashFromTagMap(distributedCache, tag, cacheKey, token);
        }
 public async static Task RemoveAsync(this IDistributedCache distributedCache, Tag.Name tag, CancellationToken token = default)
 {
     await RemoveHashesAndTagMap(distributedCache, tag, token);
 }
        public async static Task <T> GetAsync <T>(this IDistributedCache distributedCache, Tag.Name tag, object parameters, CancellationToken token = default) where T : class
        {
            T      value    = default;
            string cacheKey = GetCacheKey(tag, value, parameters);
            var    result   = await distributedCache.GetAsync(cacheKey, token);

            value = result.FromByteArray <T>();
            return(value);
        }
        public async static Task SetAsync <T>(this IDistributedCache distributedCache, Tag.Name tag, object parameters, T value, DistributedCacheEntryOptions options, CancellationToken token = default)
        {
            string cacheKey = GetCacheKey(tag, value, parameters);
            await distributedCache.SetAsync(cacheKey, value.ToByteArray(), options, token);

            await InsertHashIntoTagMap(distributedCache, tag, cacheKey, token);
        }
        public async static Task RemoveHashesAndTagMap(IDistributedCache distributedCache, Tag.Name tag, CancellationToken token = default)
        {
            string masterKey = string.Format("{0}_{1}", "master", tag.ToString());
            var    hashes    = (await distributedCache.GetAsync(masterKey, token)).FromByteArray <List <string> >();

            if (hashes == null)
            {
                hashes = new List <string>();
            }
            foreach (var hash in hashes)
            {
                await distributedCache.RemoveAsync(hash, token);
            }
            await distributedCache.RemoveAsync(masterKey, token);
        }
        public async static Task <T> FromAsync <T>(this IDistributedCache distributedCache, Tag.Name tag, object parameters, Func <Task <T> > query, DistributedCacheEntryOptions options, CancellationToken token = default) where T : class
        {
            T result = await distributedCache.GetAsync <T>(tag, parameters, token);

            if (result == null)
            {
                result = await query.Invoke();
                await SetAsync <T>(distributedCache, tag, parameters, result, options, token);
            }
            return(result);
        }
        public async static Task RemoveHashFromTagMap(IDistributedCache distributedCache, Tag.Name tag, string cacheKey, CancellationToken token = default)
        {
            string masterKey = string.Format("{0}_{1}", "master", tag.ToString());
            var    hashes    = (await distributedCache.GetAsync(masterKey, token)).FromByteArray <List <string> >();

            if (hashes == null)
            {
                hashes = new List <string>();
            }
            if (hashes.Contains(cacheKey))
            {
                hashes.Remove(cacheKey);
                await distributedCache.SetAsync(masterKey, hashes.ToByteArray(), new DistributedCacheEntryOptions()
                {
                    AbsoluteExpiration = null
                }, token);
            }
        }