Try your search with a different keyword or use * as a wildcard.
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Primitives;
using Nop.Core.Configuration;
namespace Nop.Core.Caching;
///
/// Represents a memory cache manager
///
///
/// This class should be registered on IoC as singleton instance
///
public partial class MemoryCacheManager : CacheKeyService, IStaticCacheManager
{
#region Fields
// Flag: Has Dispose already been called?
protected bool _disposed;
protected readonly IMemoryCache _memoryCache;
///
/// Holds the keys known by this nopCommerce instance
///
protected readonly ICacheKeyManager _keyManager;
protected static CancellationTokenSource _clearToken = new();
#endregion
#region Ctor
public MemoryCacheManager(AppSettings appSettings, IMemoryCache memoryCache, ICacheKeyManager cacheKeyManager)
: base(appSettings)
{
_memoryCache = memoryCache;
_keyManager = cacheKeyManager;
}
#endregion
#region Utilities
///
/// Prepare cache entry options for the passed key
///
/// Cache key
/// Cache entry options
protected virtual MemoryCacheEntryOptions PrepareEntryOptions(CacheKey key)
{
//set expiration time for the passed cache key
var options = new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(key.CacheTime)
};
//add token to clear cache entries
options.AddExpirationToken(new CancellationChangeToken(_clearToken.Token));
options.RegisterPostEvictionCallback(OnEviction);
_keyManager.AddKey(key.Key);
return options;
}
///
/// The callback method which gets called when a cache entry expires.
///
/// The key of the entry being evicted.
/// The value of the entry being evicted.
/// The .
/// The information that was passed when registering the callback.
protected virtual void OnEviction(object key, object value, EvictionReason reason, object state)
{
switch (reason)
{
// we clean up after ourselves elsewhere
case EvictionReason.Removed:
case EvictionReason.Replaced:
case EvictionReason.TokenExpired:
break;
// if the entry was evicted by the cache itself, we remove the key
default:
_keyManager.RemoveKey(key as string);
break;
}
}
#endregion
#region Methods
///
/// Remove the value with the specified key from the cache
///
/// Cache key
/// Parameters to create cache key
/// A task that represents the asynchronous operation
public Task RemoveAsync(CacheKey cacheKey, params object[] cacheKeyParameters)
{
var key = PrepareKey(cacheKey, cacheKeyParameters).Key;
_memoryCache.Remove(key);
_keyManager.RemoveKey(key);
return Task.CompletedTask;
}
///
/// Get a cached item. If it's not in the cache yet, then load and cache it
///
/// Type of cached item
/// Cache key
/// Function to load item if it's not in the cache yet
///
/// A task that represents the asynchronous operation
/// The task result contains the cached value associated with the specified key
///
public async Task GetAsync(CacheKey key, Func> acquire)
{
if ((key?.CacheTime ?? 0) <= 0)
return await acquire();
var task = _memoryCache.GetOrCreate(
key.Key,
entry =>
{
entry.SetOptions(PrepareEntryOptions(key));
return new Lazy>(acquire, true);
});
try
{
return await task!.Value;
}
catch
{
//if a cached function throws an exception, remove it from the cache
await RemoveAsync(key);
throw;
}
}
///
/// Get a cached item. If it's not in the cache yet, return a default value
///
/// Type of cached item
/// Cache key
/// A default value to return if the key is not present in the cache
///
/// A task that represents the asynchronous operation
/// The task result contains the cached value associated with the specified key, or the default value if none was found
///
public async Task GetAsync(CacheKey key, T defaultValue = default)
{
var value = _memoryCache.Get>>(key.Key)?.Value;
try
{
return value != null ? await value : defaultValue;
}
catch
{
//if a cached function throws an exception, remove it from the cache
await RemoveAsync(key);
throw;
}
}
///
/// Get a cached item. If it's not in the cache yet, then load and cache it
///
/// Type of cached item
/// Cache key
/// Function to load item if it's not in the cache yet
///
/// A task that represents the asynchronous operation
/// The task result contains the cached value associated with the specified key
///
public async Task GetAsync(CacheKey key, Func acquire)
{
return await GetAsync(key, () => Task.FromResult(acquire()));
}
///
/// Get a cached item as an instance, or null on a cache miss.
///
/// Cache key
///
/// A task that represents the asynchronous operation
/// The task result contains the cached value associated with the specified key, or null if none was found
///
public async Task