Kzryzstof
Kzryzstof

Reputation: 8392

Why is IMemoryCache's TryGetValue throwing an InvalidOperationException?

In my Web application, I have one of my services that uses an injected IMemoryCache:

public class InternalService
{
    private readonly IMemoryCache m_memoryCache;

    private readonly MemoryCacheEntryOptions m_cacheEntryOptions;

    public Service(IMemoryCache memoryCache)
    {
         m_memoryCache = memoryCache;

         // Set cache options: keep in cache for this time, reset time in 1 hour, no matter what.
        m_cacheEntryOptions = new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(1d));
    }
} 

In this service, I am using the cache to avoid an expensive call. The call returns a list of Entity:

public class Entity
{
    public long Id {get; set;}    
}

Here is the method in the Service that deals with the cache:

private async IList<Entity> GetEntitiesAsync(string tenantId)
{
    if (false == m_memoryCache.TryGetValue(tenantId, out IList<Entity> tenantEntities) || tenantEntities.Count == 0)
    {
         // Do the expensive call.
         IList<Entity> tenantEntities = await ExpensiveServiceCallAsync(tenantId);

         m_memoryCache.Set(tenantId, tenantEntities , m_cacheEntryOptions);
    }

    return tenantEntities;
}

However, it does throw the following exception:

System.InvalidCastException: Unable to cast object of type 'System.String' to type 'System.Collections.Generic.IList`1[Entity]'. at Microsoft.Extensions.Caching.Memory.CacheExtensions.TryGetValue[TItem](IMemoryCache cache, Object key, TItem& value)

As specified in the Microsoft documentation, it says that :

The in-memory cache can store any object; the distributed cache interface is limited to byte[].

Question

What am I doing wrong? I do not understand why the cache is expecting to return a string when I was supposed to cache a list of Entity.

Upvotes: 0

Views: 3009

Answers (1)

Janus Pienaar
Janus Pienaar

Reputation: 1103

I've got a suspicion that somewhere in your code you are adding a string value to the cache with the same tenantId that you are using here.

Remember, that m_memoryCache instance is used throughout your code.

Upvotes: 3

Related Questions