I have used Alastair Crabtree’s LazyCache (read-through in-memory cache) on a couple of other projects e.g. The Things Industries V3 Connector (DeviceClient instances) and Swarm Space Azure IoT Connector (DeviceClient Instances and CS-Script binaries).
Adding LazyCache support to an ASP.Net Core WebAPI application is one line of code.
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddApplicationInsightsTelemetry();
// Add services to the container.
builder.Services.AddTransient<IDapperContext>(s => new DapperContext(builder.Configuration));
builder.Services.AddControllers();
// Register IAppCache as a singleton CachingService
builder.Services.AddLazyCache();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.MapControllers();
app.Run();
}
One of the applications I work uses a lot of “reference” data which is effectively static e.g. national/regional holidays in countries where they have customers, and data which is updated on a schedule e.g. exchange rates downloaded at a known time every day.
//...
private readonly TimeSpan StockItemListAbsoluteExpirationTime = new TimeSpan(23, 59, 59);
//....
private async Task<IEnumerable<Model.StockItemListDtoV1>> GetStockItemsAsync()
{
return await dbConnection.QueryWithRetryAsync<Model.StockItemListDtoV1>(sql: sqlCommandText, commandType: CommandType.Text);
}
[HttpGet]
public async Task<ActionResult<IEnumerable<Model.StockItemListDtoV1>>> Get()
{
MemoryCacheEntryOptions memoryCacheEntryOptions = new MemoryCacheEntryOptions()
{
Priority = CacheItemPriority.NeverRemove,
AbsoluteExpiration = DateTime.UtcNow.Date.Add(StockItemListAbsoluteExpirationTime)
};
return this.Ok(await cache.GetOrAddAsync("StockItems", () => GetStockItemsAsync(), memoryCacheEntryOptions));
}
[HttpDelete()]
public ActionResult Delete()
{
cache.Remove("StockItems");
return this.Ok();
}
For the holiday information updates, the dataset could be deleted(“burped”) then refreshed the next time it is referenced or deleted then re-loaded. For exchange rate updates the cache could automatically expire the dataset shortly after the scheduled download.

When I deployed my demo application to an Azure AppService the requests (using the composer tab of Telerik Fiddler) took longer than when the application was running on my development box which was unexpected. I think this was because the JavaScript Object Notation(JSON) response payload was larger than the AzureSQL Tabular Data Stream(TDS) payload.
The LazyCache source code hasn’t been updated for quite a while (but it is quite stable and works well) and moving to other libraries has been recommended in the wiki.