Caching data backend–.NET Core–part 49

We have 2 options to cache data: One in webAPI, one when returns from database.

For WebAPI, I have read https://docs.microsoft.com/en-us/aspnet/core/performance/caching/response?view=aspnetcore-3.1

and

https://docs.microsoft.com/en-us/aspnet/core/performance/caching/middleware?view=aspnetcore-3.1

It is also important to read the conditions for caching : https://docs.microsoft.com/en-us/aspnet/core/performance/caching/middleware?view=aspnetcore-3.1#conditions-for-caching ( e.g. only GET or HEAD is cached)

It is just very easy – see github commit https://github.com/ignatandrei/InfoValutar/commit/b8d38658b5135e4d3c93da78f77ffb9f01376829

Also, can be tested by setting a breakpoint in VisualStudio  – see that is activated just 1 time.

Now, the interesting part – I need the cache for the remaining of the day, in case the exchange rate is in the same day .

Because I need this functionality for both ECB and BNR banks( and may for others), I either create a C# extension, either a base class (instead of an interface ) , either I use a feature of C# 8,  interface that have implementations.

The first try is here: https://github.com/ignatandrei/InfoValutar/commit/3aeeab7a5c519493764a365885b812f3da6ccb8e

Where I have do the code wrong: the key to cache and the items to cache are different. See

https://github.com/ignatandrei/InfoValutar/commit/a68da1f16a27ae06c7978d3acd9b2f1ba1bebc0f

I am using Memory Cache

namespace InfoValutarShared
{
#pragma warning disable IDE1006 // Naming Styles
public interface BankGetExchange
#pragma warning restore IDE1006 // Naming Styles
{
public string Bank { get; }
Task<IEnumerable<ExchangeRates>> GetActualRates();
DateTime Key()
{
var now = DateTime.UtcNow;
if (now.DayOfWeek == DayOfWeek.Sunday)
now = now.AddDays(-1);
if (now.DayOfWeek == DayOfWeek.Saturday)
now = now.AddDays(-1);
return now;

}
IEnumerable<ExchangeRates> TodayFromCache
{
get

{
var keyDate = Key();
string key = $”{this.Bank}_{keyDate.ToString(“yyyyMMdd”)}”;
var mc = MemoryCache.Default;
if (mc.Contains(key))
return mc[key] as ExchangeRates[];

return null;

}
set
{
var keyDate = Key();
string key = $”{this.Bank}_{keyDate.ToString(“yyyyMMdd”)}”;
var mc = MemoryCache.Default;
value = value
.Where(it => Math.Abs(it.Date.Subtract(keyDate).TotalDays) < 1)
.ToArray();
if (value.Any())
{
mc.Set(key, value, DateTime.UtcNow.AddDays(7));

}
}
}

}
}

and using this like this

public async Task<IEnumerable<ExchangeRates>> GetActualRates()
{
var b = this as BankGetExchange;
if (b.TodayFromCache != null)
return b.TodayFromCache;

//code omitted

}
b.TodayFromCache = ret;

return ret;

 

And this is it…