📜  ASP.NET Core 从 IMemoryCache 设置更新清除缓存(由 CacheExtensions 类的 Set 方法设置) - C# 代码示例

📅  最后修改于: 2022-03-11 14:49:12.454000             🧑  作者: Mango

代码示例3
serviceCollection.AddSingleton();

public interface IMyCache : IEnumerable>, IMemoryCache
{
    /// 
    /// Clears all cache entries.
    /// 
    void Clear();
}

public class MyMemoryCache : IMyCache
{
    private readonly IMemoryCache _memoryCache;
    private readonly ConcurrentDictionary _cacheEntries = new ConcurrentDictionary();

    public MyMemoryCache(IMemoryCache memoryCache)
    {
        this._memoryCache = memoryCache;
    }

    public void Dispose()
    {
        this._memoryCache.Dispose();
    }

    private void PostEvictionCallback(object key, object value, EvictionReason reason, object state)
    {
        if (reason != EvictionReason.Replaced)
            this._cacheEntries.TryRemove(key, out var _);
    }

    /// 
    public bool TryGetValue(object key, out object value)
    {
        return this._memoryCache.TryGetValue(key, out value);
    }

    /// 
    /// Create or overwrite an entry in the cache and add key to Dictionary.
    /// 
    /// An object identifying the entry.
    /// The newly created  instance.
    public ICacheEntry CreateEntry(object key)
    {
        var entry = this._memoryCache.CreateEntry(key);
        entry.RegisterPostEvictionCallback(this.PostEvictionCallback);
        this._cacheEntries.AddOrUpdate(key, entry, (o, cacheEntry) =>
        {
            cacheEntry.Value = entry;
            return cacheEntry;
        });
        return entry;
    }

    /// 
    public void Remove(object key)
    {
        this._memoryCache.Remove(key);
    }

    /// 
    public void Clear()
    {
        foreach (var cacheEntry in this._cacheEntries.Keys.ToList())
            this._memoryCache.Remove(cacheEntry);
    }

    public IEnumerator> GetEnumerator()
    {
        return this._cacheEntries.Select(pair => new KeyValuePair(pair.Key, pair.Value.Value)).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }

    /// 
    /// Gets keys of all items in MemoryCache.
    /// 
    public IEnumerator Keys => this._cacheEntries.Keys.GetEnumerator();
}

public static class MyMemoryCacheExtensions
{
    public static T Set(this IMyCache cache, object key, T value)
    {
        var entry = cache.CreateEntry(key);
        entry.Value = value;
        entry.Dispose();

        return value;
    }

    public static T Set(this IMyCache cache, object key, T value, CacheItemPriority priority)
    {
        var entry = cache.CreateEntry(key);
        entry.Priority = priority;
        entry.Value = value;
        entry.Dispose();

        return value;
    }

    public static T Set(this IMyCache cache, object key, T value, DateTimeOffset absoluteExpiration)
    {
        var entry = cache.CreateEntry(key);
        entry.AbsoluteExpiration = absoluteExpiration;
        entry.Value = value;
        entry.Dispose();

        return value;
    }

    public static T Set(this IMyCache cache, object key, T value, TimeSpan absoluteExpirationRelativeToNow)
    {
        var entry = cache.CreateEntry(key);
        entry.AbsoluteExpirationRelativeToNow = absoluteExpirationRelativeToNow;
        entry.Value = value;
        entry.Dispose();

        return value;
    }

    public static T Set(this IMyCache cache, object key, T value, MemoryCacheEntryOptions options)
    {
        using (var entry = cache.CreateEntry(key))
        {
            if (options != null)
                entry.SetOptions(options);

            entry.Value = value;
        }

        return value;
    }

    public static TItem GetOrCreate(this IMyCache cache, object key, Func factory)
    {
        if (!cache.TryGetValue(key, out var result))
        {
            var entry = cache.CreateEntry(key);
            result = factory(entry);
            entry.SetValue(result);
            entry.Dispose();
        }

        return (TItem)result;
    }

    public static async Task GetOrCreateAsync(this IMyCache cache, object key, Func> factory)
    {
        if (!cache.TryGetValue(key, out object result))
        {
            var entry = cache.CreateEntry(key);
            result = await factory(entry);
            entry.SetValue(result);
            entry.Dispose();
        }

        return (TItem)result;
    }
}