How To Use In-Memory Cache In An ASP.NET Core Web API

Before we can dive into the In-Memory Cache implementation, first, What is caching and when you should consider using it?

Well, caching is basically a technique of storing frequently used data in a temporary storage. Caching can significantly improve the performance and scalability of any application by reducing the time and resources required to load fresh contents. Using that technique will definitely make the end user much happier to use the app.

Types of Caching supported by ASP.Net Core

As you might already know ASP.NET Core supports different types of caching such as In-Memory Cache, Distributed Cache and Response Cache. However, in this post I will take the opportunity to introduce you to how to use In-Memory Cache in an ASP.Net Core Web API app.

How data is stored

When using the In-Memory Cache feature, the data is stored in the memory of Web Server where a web application is being hosted at. It’s good to remember that an application can be hosted on single Server or multiple Servers in a Server Farm. For those of you that have a single server, you should be just fine using In-Memory Cache with no issues because it doesn’t require much to get running, however, if those running on multiple servers on a server farm MUST ensure that the sessions are sticky.

Setting cache expiration time

When adding an item to the cache you set an expiration, this can be an absolute time, a sliding window or the combination of both. Choosing which one to use depends on your scenario.

Example of how to implement In-Memory Cache

To keep thing simple and easy to follow I am going to implement a quick sample API to retrieve the states name using state abbreviation as code. In order to get start simple create a new blank WEB API project in Visual Studio and follow the steps below to fill in the required pieces or you can download the full sample code from github here.

Injecting the dependency from the startup.cs.

    public void ConfigureServices(IServiceCollection services)
    {
      services.AddMemoryCache();
      services.AddMvc();
    }

Now that the In-Memory Cache service has been added, I can access the cache from inside the controllers by simply injecting an IMemoryCache parameter in the constructors.

    private readonly IMemoryCache _cache;

    public StatesController(IMemoryCache memoryCache)
    {
      _cache = memoryCache;
    }

Get Method setup

Next, I need to set my cache inside the get action method which is used to get the name of the state that matches the search criteria.

   [HttpGet("{stateCode}")]
   public async Task Get(string stateCode)
   {
      string state = string.Empty;
      if (!_cache.TryGetValue("CashedStatesList", out Dictionary states))
      {
       Console.WriteLine("Loading from database or json file into cache");

        states =
           JsonConvert.DeserializeObject>(
           await System.IO.File.ReadAllTextAsync("StatesList.json"));

        MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
        {
         AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300), // cache will expire in 300 seconds or 5 minutes
         SlidingExpiration = TimeSpan.FromSeconds(60) // cache will expire if inactive for 60 seconds
        };

        if (states != null)
        _cache.Set("CashedStatesList", states, options);
      }
      else
      {
         Console.WriteLine("***Data Found in Cache...***");
      }

      if (states != null)
      {
         state = states.GetValueOrDefault(stateCode);

         if (string.IsNullOrEmpty(state))
         {
           state = "Not found, please try again.";
         }

      }

      if (string.IsNullOrEmpty(state))
      {
         return NoContent();
      }
      return Ok(state);
  }

Reading from data source

In the code snippet above as you can see the very first if condition is checking against the cache dictionary object to load the states list if exist, otherwise, it will continue and load the states from the json file. To be clear here’s the snippet of code that reads the json file and load the states list.

  states =
           JsonConvert.DeserializeObject>(
           await System.IO.File.ReadAllTextAsync("StatesList.json"));

Set cache expiration

Then, once the data was cached, I set some times to when it will expire which is 5 minutes and if no activity they will expire in 60 seconds. You can set these values according to your requirements.

   MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
   {
     AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300), // cache will expire in 300 seconds or 5 minutes
     SlidingExpiration = TimeSpan.FromSeconds(60) // cache will expire if inactive for 60 seconds
   };

Then, if you continue reading the code above you will notice where the cache is being set as expected.
Last, as you can see from this simple example, the In-Memory cache is can be very beneficial when hosting an application on a single Server. It stores data on Server and improves application performance. Don’t forget to test your app to not depend solely on cached data.
In case you would like to read more about In-Memory cache, please visit these links below.
Cache in-memory in ASP.NET Core

Leave a Reply

Your email address will not be published. Required fields are marked *