In this post let’s go through how server-side caching can be used in an ASP.NET Core Application, specially in-memory caching.
Caching can be used to improve the performance of an application. For an example, say that you have an API endpoint and there, you are returning some data after querying a database, and you are sure the related data is not going to get refreshed for a certain period of time, maybe daily. In that case, there is no point of querying the database each time your endpoint is being called within that day. So in the initial call, you can query the database, cache them and for the next subsequent calls, you can return the data from the cache. Then after that certain period of time expires, elicit the data in the cache and start from the beginning.
The in-memory caching uses web servers memory to store the cache. So now an interesting question comes, what if the application is running on multiple servers then how can the cache is shared. In such scenario, either we will need to enforce sticky sessions (specific session and all its subsequent sessions being directed to the same server) or distributed caching (doesn't use local memory and uses some other providers to maintain the cache Microsoft SQL Server, Redis etc.). In this post, we are assuming sticky sessions are in place.
ASP.NET Core provides 2 options.
public class MemoryCache : IDisposable, Microsoft.Extensions.Caching.Memory.IMemoryCache
public class MemoryCache : System.Runtime.Caching.ObjectCache, IDisposable
This one comes for .NET Framework, but still as long you target .NET Standard 2.0 or above, you can use this.
Now let’s see how we can use in-memory caching using Microsoft.Extensions.Caching.Memory.MemoryCache.
I have created an ASP.NET Core Web API application using the default template.
First, you need to register IMemoryCache. We don’t explicitly need to register, there is an extension method already available.
public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); services.AddMemoryCache(); }
Next, in the controllers’ constructor, I can inject IMemoryCache.
public IMemoryCache _memoryCache { get; } public ValuesController(IMemoryCache memoryCache) { _memoryCache = memoryCache; }
And use as follows.
[HttpGet] public ActionResult<IEnumerable<string>> Get() { string key = "Somekey"; if (!_memoryCache.TryGetValue(key, out DateTime cacheValue)) { cacheValue = DateTime.Now; var cacheEntryOptions = new MemoryCacheEntryOptions() .SetSlidingExpiration(TimeSpan.FromSeconds(30)); _memoryCache.Set(key, cacheValue, cacheEntryOptions); } return new string[] { $"Cached: { cacheValue.ToString()}", $"Actual: { DateTime.Now.ToString()}" }; }
The cache contains EntriesCollection which is maintained using keys. The logic is simple, we are adding items to EntriesCollection identified by a key, and when we add we can set a variety of options (MemoryCacheEntryOptions).
- AbsoluteExpiration
- AbsoluteExpirationRelativeToNow
- ExpirationTokens
- PostEvictionCallbacks
- Priority
- Size
- SlidingExpiration
More reading,
Cache in-memory in ASP.NET Core
Hope this helps.
Happy Coding.
Regards,
Jaliya