Search code examples
c#asp.net-core.net-corecachingin-memory-cache

Get value of vary-by attribute of <cache> tag helper from c#


I want to clear the memory cache by a specific key generated by the tag helper. It is possible to clear the whole memory cache generated by the cache tag using the below code.

public partial class MemoryCacheManager : CacheKeyService, ILocker, IStaticCacheManager
{
    private readonly CacheTagHelperMemoryCacheFactory _factory;
    public MemoryCacheManager(AppSettings appSettings, IMemoryCache memoryCache, 
                        CacheTagHelperMemoryCacheFactory factory) : base(appSettings)
    {
        _memoryCache = memoryCache;
        _factory = factory;
    }

    public Task ClearAsync()
    {
        PropertyInfo prop = _factory.Cache.GetType().GetProperty("EntriesCollection", BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Public);
        var allInnerCacheTags = prop.GetValue(_factory.Cache) as ICollection;

        foreach (var item in allInnerCacheTags)
        {
            object cacheKeyOfTag = item.GetType().GetProperty("Key",  BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Public);
            _memoryCache.Remove(cacheKeyOfTag);
        }
    }
}

But I want to remove cache entry by specific key like the attached image. enter image description here

Is there any way to get the value of the _varyBy.


Solution

  • I am able to get the value of the "_varyBy". Below code work for me net5.0. Assume also work for the net3.2

    public partial class MemoryCacheManager
    {
        private readonly CacheTagHelperMemoryCacheFactory _factory;
        private readonly IMemoryCache _memoryCache;
    
        public MemoryCacheManager(IMemoryCache memoryCache, 
                                  CacheTagHelperMemoryCacheFactory factory)
        {
            _memoryCache = memoryCache;
            _factory = factory;
        }
    
        public void ClearCacheTagAsync(string cachekey)
        {
            PropertyInfo prop = _factory.Cache.GetType().GetProperty("EntriesCollection", BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Public);
            var allInnerCacheTags = prop.GetValue(_factory.Cache) as ICollection;
            foreach (var cacheEntry in allInnerCacheTags)
            {
                var theKeyValueOfEntry = cacheEntry.GetType().GetProperties().ToDictionary(property => property.Name, property => property.GetValue(cacheEntry));
    
                var item = theKeyValueOfEntry.FirstOrDefault();
                var cacheTag = ((CacheTagKey)item.Value);
                var field = cacheTag.GetType().GetField("_varyBy", BindingFlags.NonPublic | BindingFlags.Instance);
                var actualValue = field.GetValue(cacheTag);
    
                if (cachekey == actualValue.ToString())
                {
                    _memoryCache.Remove(cacheEntry);
                }
            }
        }    
    }