I have the following situation:
//IMemoryCache is injected into class and into field _cache
public void IncreaseCounter(string key){
int currectCount = _cache.Get<int>(key) 1;
_cache.Set<int>(key, currentCount);
}
However I am aware that this is not the best method to do it. I would also like to check if the key does exist, if it does not, the counter should be 0
and then increased to 1
.
How would I do this ? I know of the method GetOrCreate(object, Func<>)
but I don't know how to implement this.
CodePudding user response:
GetOrCreate basically works like this:
int currentCount = _cache.GetOrCreate(key, _ => 0); // pass key and
// "new item factory"
// now, if key exists, it will return the cached value
// if it does not exist, it will
// - create a new entry,
// - execute the passed-in factory function und set the returned value in cache,
// - return the result of the passed-in factory
_cache.Set(key, currentCount 1);
The expected factory must be a Func<ICacheEntry, TItem>
which translate to delegate of this form: TItem FunctionName(ICacheEntry entry)
. So, a function that takes a parammeter of type ICacheEntry
and returns whatever type your values shall be.
_ => 0
matches this in that it is a Func, that ignores the input param and just returns 0, which should be enough for the use case from the question.
See an Example in Fiddle
using System;
using Microsoft.Extensions.Caching.Memory;
public class Program
{
public static void Main()
{
IMemoryCache cache = new MemoryCache(new MemoryCacheOptions());
object key = new object();
Console.WriteLine("{0}", cache.TryGetValue(key, out int val)?val:"key not found");
Incr(key, cache);
Console.WriteLine(cache.Get(key));
Incr(key, cache);
Console.WriteLine(cache.Get(key));
}
public static void Incr(object key, IMemoryCache cache)
{
int currentValue = cache.GetOrCreate(key, _ => 0);
cache.Set(key, currentValue 1);
}
}
Produces
key not found 1 2
Just for your information - not relevant to the specific use case in question:
Mind that I used the "ignore" ( _ =>
) here. If you need to, you can actually use information from the newly created cache entry from within the factory (or set values on it):
int currentValue = cache.GetOrCreate(key, entry => DoDBLookup(entry.Key));
for example, if you wanted to read-through to a database. Or set expiry, compute intial value based on key, etc ...