Reputation: 30342
There are a few things I'd like to cache without relying on Redis. My app is an ASP.NET Core API app running on Azure App Service.
For example, I create a list of countries from
CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.SpecificCultures);
I can save this in Redis but it'll cost money and this is not a list that changes often and is produced from the framework so even if I'm running multiple instances of my API app, lists will be identical.
How do I save this in memory without Redis? I can call a method that generates this list in my Startup.cs
but where do I store it and how do I retrieve it?
Upvotes: 2
Views: 2013
Reputation: 56869
AspNetCore has a built-in memory cache that you can use to store pieces of data that are shared between requests.
Register the cache at startup...
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache();
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseMvcWithDefaultRoute();
}
}
And you can inject it like...
public class HomeController : Controller
{
private IMemoryCache _cache;
public HomeController(IMemoryCache memoryCache)
{
_cache = memoryCache;
}
public IActionResult Index()
{
string cultures = _cache[CacheKeys.Cultures] as CultureInfo[];
return View();
}
To make it work application wide, you can use a facade service with strongly-typed members combined with some sort of cache refresh pattern:
public CultureInfo[] Cultures { get { return GetCultures(); } }
private CultureInfo[] GetCultures()
{
CultureInfo[] result;
// Look for cache key.
if (!_cache.TryGetValue(CacheKeys.Cultures, out result))
{
// Key not in cache, so get data.
result = CultureInfo.GetCultures(CultureTypes.SpecificCultures);
// Set cache options.
var cacheEntryOptions = new MemoryCacheEntryOptions()
// Keep in cache for this time, reset time if accessed.
.SetSlidingExpiration(TimeSpan.FromMinutes(60));
// Save data in cache.
_cache.Set(CacheKeys.Cultures, result, cacheEntryOptions);
}
return result;
}
Of course, you could clean that up by making it into a service that accepts the cache as a dependency which you can inject wherever it is needed, but that is the general idea.
Note also there is a distributed cache in case you want to share data between web servers.
Upvotes: 2