/// <summary>
        /// Get a localized string for the provided key and culture
        /// </summary>
        /// <param name="key">The key</param>
        /// <param name="culture">The culture</param>
        /// <param name="updateLastUsed">Indicate if the LastUsed property of the record needs to be updated</param>
        /// <returns>A localized string</returns>
        public string GetString(string key, CultureInfo culture, bool updateLastUsed)
        {
            if (culture == null)
            {
                throw new ArgumentNullException(nameof(culture));
            }
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }

            var cacheKey = CacheKeyProvider.GetSpecificCacheKey(culture, _baseName, key);

            var localization = _memoryCache.GetOrCreate(cacheKey, entry =>
            {
                entry.AbsoluteExpirationRelativeToNow = _globalizationOptions.Value.CacheTime;

                var context = _contextAccessor.HttpContext.RequestServices.GetService <LocalizationContext>();
                return(_getLocalizationString(context, culture, _baseName, key, updateLastUsed));
            });

            if (localization == null)
            {
                _memoryCache.Remove(cacheKey);
            }
            return(localization);
        }
예제 #2
0
        public void GetTypeNameRepresentation_ReturnsExpectedValues()
        {
            var argument       = CacheKeyProviderExecutionOrder.Enum;
            var result         = CacheKeyProvider.GetTypeNameRepresentation(argument);
            var expectedResult = $"Enum[{argument.GetType().Name}]";

            Assert.AreEqual(expectedResult, result);
        }
예제 #3
0
        public void GetValueRepresentation_ReturnsExpectedValues()
        {
            var argument       = CacheKeyProviderExecutionOrder.Enum;
            var result         = CacheKeyProvider.GetValueRepresentation(argument);
            var expectedResult = ((int)argument).ToString();

            Assert.AreEqual(expectedResult, result);
        }
예제 #4
0
 /// <summary>
 /// Revalidate caches after call method
 /// </summary>
 /// <param name="actionExecutedContext"></param>
 /// <returns></returns>
 public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
 {
     if (actionExecutedContext.ActionContext.Response != null && actionExecutedContext.ActionContext.Response.IsSuccessStatusCode)
     {
         var invocation      = GetInvocation(actionExecutedContext.ActionContext);
         var revalidatedKeys = KeyFormats.Select(k => CacheKeyProvider.GetRevalidateKey(invocation, k)).ToList();
         Global.RevalidateCaches(revalidatedKeys);
     }
 }
예제 #5
0
        /// <summary>
        /// Revalidate caches after call method
        /// </summary>
        /// <param name="actionExecutedContext"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public override Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
        {
            if (actionExecutedContext.ActionContext.Response != null && actionExecutedContext.ActionContext.Response.IsSuccessStatusCode)
            {
                var invocation      = GetInvocation(actionExecutedContext.ActionContext);
                var revalidatedKeys = KeyFormats.Select(k => CacheKeyProvider.GetRevalidateKey(invocation, k)).ToList();

                return(Global.RevalidateCachesAsync(revalidatedKeys));
            }
            return(TaskHelpers.DefaultCompleted);
        }
예제 #6
0
        public void GenerateCacheKeyFromRequest_WhenNoParametersArePassed_ShouldReturnEmptyString()
        {
            //Arrange
            var sut = new CacheKeyProvider(_encoderMock.Object);

            //Act
            var result = sut.GenerateCacheKeyFromRequest();

            //Assert
            result.Should().BeNullOrEmpty();
        }
예제 #7
0
        /// <summary>
        /// Get empty list change monitor
        /// </summary>
        /// <param name="invocation"></param>
        /// <param name="invocationContext"></param>
        /// <returns></returns>
        public virtual IEnumerable <IChangeMonitor> GetChangeMonitors(_IInvocation invocation, IDictionary <string, object> invocationContext)
        {
            var att = invocationContext.TryGetByKey <ICacheSettings>(Global.__flatwhite_outputcache_attribute, OutputCacheAttribute.Default);

            if (string.IsNullOrWhiteSpace(att?.RevalidateKeyFormat))
            {
                yield break;
            }

            var revalidationKey = CacheKeyProvider.GetRevalidateKey(invocation, att.RevalidateKeyFormat);

            yield return(new FlatwhiteCacheEntryChangeMonitor(revalidationKey));
        }
예제 #8
0
        public void GenerateCacheKeyFromRequest_WhenParametersArePassed_ShouldConcatenateParameters()
        {
            //Arrange
            _encoderMock.Setup(x => x.Encode(It.IsAny <string>())).Returns <string>(val => val);
            var values        = new[] { "test1", "test2" };
            var expectedValue = "test1_test2";
            var sut           = new CacheKeyProvider(_encoderMock.Object);

            //Act
            var result = sut.GenerateCacheKeyFromRequest(values);

            //Assert
            result.Should().Be(expectedValue);
        }
예제 #9
0
        /// <summary>
        /// Cache all keys from which a record was recently used
        /// </summary>
        /// <param name="maxAge">The maximum age of the record LastUsed param</param>
        /// <param name="absoluteExpirationRelativeToNow">The absolute expiration relative to now</param>
        public void CacheRecentlyUsed(TimeSpan maxAge, TimeSpan?absoluteExpirationRelativeToNow = null)
        {
            var lastUsed = DateTime.UtcNow - maxAge;
            var records  = _context.LocalizationKeys
                           .Where(k => k.Records.Any(r => r.LastUsed >= lastUsed))
                           .SelectMany(k => k.Records)
                           .Select(r => new { r.Text, r.LocalizationKey.Base, r.LocalizationKey.Key, CultureName = r.Culture.Name })
                           .ToArray();

            foreach (var record in records)
            {
                var cacheKey = CacheKeyProvider.GetSpecificCacheKey(record.CultureName, record.Base, record.Key);
                _memoryCache.Set(cacheKey, record.Text, absoluteExpirationRelativeToNow.Value);
            }
        }
예제 #10
0
        public void GenerateCacheKeyFromRequest_WhenParametersArePassed_ShouldReturnEncodedValue()
        {
            //Arrange
            var values = new[] { "test1", "test2" };
            var expectedValueFromEncoder = "asdasdwdawd";

            _encoderMock.Setup(x => x.Encode(It.IsAny <string>())).Returns <string>(val => expectedValueFromEncoder);
            var sut = new CacheKeyProvider(_encoderMock.Object);

            //Act
            var result = sut.GenerateCacheKeyFromRequest(values);

            //Assert
            result.Should().Be(expectedValueFromEncoder);
        }
예제 #11
0
        public void GenerateCacheKeyFromRequest_WhenParametersArePassed_ShouldEncodeConcatenatedValue()
        {
            //Arrange
            var values = new[] { "test1", "test2" };
            var expectedValuePassedToEncoder = "test1_test2";

            _encoderMock.Setup(x => x.Encode(It.IsAny <string>())).Returns <string>(val => val);
            var sut = new CacheKeyProvider(_encoderMock.Object);

            //Act
            sut.GenerateCacheKeyFromRequest(values);

            //Assert
            _encoderMock.Verify(x => x.Encode(expectedValuePassedToEncoder), Times.Once);
        }
예제 #12
0
        public T ProcessExecutingCommands <T>(DbCommand command, DbContext context, T result)
        {
            if (command is null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            var cachePolicy = _cachePolicyManager.GetCachePolicy(command.CommandText);

            if (cachePolicy is null)
            {
                return(result);
            }

            var cacheKey = CacheKeyProvider.GetKey(command, context, cachePolicy);

            var cacheResult = _cacheProvider.Get <CachedData>(cacheKey.ToString());

            if (cacheResult.IsNull)
            {
                return(result);
            }

            if (result is InterceptionResult <DbDataReader> )
            {
                if (cacheResult.IsNull)
                {
                    using var rows = new DataReader(new TableRows());
                    return((T)Convert.ChangeType(
                               InterceptionResult <DbDataReader> .SuppressWithResult(rows),
                               typeof(T),
                               CultureInfo.InvariantCulture));
                }

                using var dataRows = new DataReader(cacheResult.Value.TableRows);
                return((T)Convert.ChangeType(
                           InterceptionResult <DbDataReader> .SuppressWithResult(dataRows),
                           typeof(T),
                           CultureInfo.InvariantCulture));
            }

            return(result);
        }
예제 #13
0
        /// <summary>
        /// Cache all keys that use the specified basekey
        /// </summary>
        /// <param name="baseKey">The basekey to preload</param>
        /// <param name="absoluteExpirationRelativeToNow">The absolute expiration relative to now</param>
        public void Cache(string baseKey, TimeSpan?absoluteExpirationRelativeToNow = null)
        {
            if (baseKey == null)
            {
                throw new ArgumentNullException(baseKey);
            }

            absoluteExpirationRelativeToNow = absoluteExpirationRelativeToNow ?? _globalizationOptions?.Value?.CacheTime ?? TimeSpan.FromDays(30);

            var records = _context.LocalizationRecords
                          .Where(r => r.LocalizationKey.Base == baseKey)
                          .Where(r => r.Culture.IsSupported)
                          .Select(r => new { r.Text, r.LocalizationKey.Base, r.LocalizationKey.Key, CultureName = r.Culture.Name })
                          .ToArray();

            foreach (var record in records)
            {
                var cacheKey = CacheKeyProvider.GetSpecificCacheKey(record.CultureName, record.Base, record.Key);
                _memoryCache.Set(cacheKey, record.Text, absoluteExpirationRelativeToNow.Value);
            }
        }
예제 #14
0
        public T ProcessExecutedCommands <T>(DbCommand command, DbContext context, T result)
        {
            if (command is null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            if (result is DataReader)
            {
                return(result);
            }

            var commandText = command.CommandText;
            var cachePolicy = _cachePolicyManager.GetCachePolicy(commandText);

            if (cachePolicy is null)
            {
                return(result);
            }

            var cacheKey = CacheKeyProvider.GetKey(command, context, cachePolicy);

            if (result is DbDataReader dataReader)
            {
                TableRows tableRows;
                using (var dbReaderLoader = new DataReaderLoader(dataReader))
                {
                    tableRows = dbReaderLoader.LoadAndClose();
                }

                _cacheProvider.Set(cacheKey.ToString(), new CachedData {
                    TableRows = tableRows
                },
                                   cachePolicy.CacheTimeout);

                return((T)(object)new DataReader(tableRows));
            }

            return(result);
        }
        /// <inheritdoc />
        public IEnumerable <string> GetAllResourceStrings(CultureInfo culture, bool throwOnMissing)
        {
            var cacheKey = CacheKeyProvider.GetBaseCacheKey(culture, _baseName);

            var resourceStrings = _memoryCache.GetOrCreate(cacheKey, entry =>
            {
                entry.AbsoluteExpirationRelativeToNow = _globalizationOptions.Value.CacheTime;
                var cultureName = culture.Name;
                var context     = _contextAccessor.HttpContext.RequestServices.GetService <LocalizationContext>();

                if (!context.SupportedCultures.Any(c => c.Name == cultureName))
                {
                    return(null);
                }

                var records = context.LocalizationRecords
                              .Where(r => r.Culture.Name == cultureName)
                              .Where(r => r.LocalizationKey.Base == _baseName)
                              .Select(r => r.Text)
                              .ToArray();

                if (!records.Any())
                {
                    return(null);
                }

                return(records);
            });

            if (resourceStrings == null)
            {
                _memoryCache.Remove(cacheKey);
                if (throwOnMissing)
                {
                    throw new Exception($"No localization keys found for culture {culture.Name} and base {_baseName}");
                }
            }
            return(resourceStrings);
        }
예제 #16
0
        /// <summary>
        /// Clear the cache with the provided revalidation keys
        /// </summary>
        /// <param name="methodExecutedContext"></param>
        /// <returns></returns>
        public override void OnMethodExecuted(MethodExecutedContext methodExecutedContext)
        {
            var revalidatedKeys = KeyFormats.Select(k => CacheKeyProvider.GetRevalidateKey(methodExecutedContext.Invocation, k)).ToList();

            Global.RevalidateCaches(revalidatedKeys);
        }
예제 #17
0
        /// <summary>
        /// Revalidate cache async
        /// </summary>
        /// <param name="methodExecutedContext"></param>
        /// <returns></returns>
        public override Task OnMethodExecutedAsync(MethodExecutedContext methodExecutedContext)
        {
            var revalidateKeys = KeyFormats.Select(k => CacheKeyProvider.GetRevalidateKey(methodExecutedContext.Invocation, k)).ToList();

            return(Global.RevalidateCachesAsync(revalidateKeys));
        }