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…