How to use in-memory caching in ASP.Net Core

Take advantage of in-memory caching in ASP.NET Core to improve the performance and scalability of your application

How to use in-memory caching in ASP.Net Core
Thinkstock

ASP.Net Core is a lean and modular framework that can be used to build high-performance, modern web applications on Windows, Linux, or MacOS. Unlike legacy ASP.Net, ASP.Net Core doesn’t have a Cache object. However, ASP.Net Core provides support for several different types of caching including in-memory caching, distributed caching, and response caching.

In this article, we’ll look at how you can boost your ASP.Net Core application’s performance and scalability by storing infrequently changing data in the in-memory cache. As always, I will include code examples to illustrate the concepts discussed. 

How to enable in-memory caching in ASP.Net Core

The in-memory cache in ASP.Net Core is a service that you can incorporate into your application using dependency injection. Once you have created an ASP.Net Core project in Visual Studio, you can enable the in-memory cache in the ConfigureServices method in the Startup class as shown in the code snippet below.

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

To work with the in-memory cache in ASP.Net Core, you need to use the IMemoryCache interface. Here is how it looks: 

public interface IMemoryCache : IDisposable
{
    bool TryGetValue(object key, out object value);
    ICacheEntry CreateEntry(object key);
    void Remove(object key);
}

You can register the IMemoryCache in the ConfigServices method using the AddMemoryCache method we examined above. Then you should inject the cache object in the constructor of your controller class as shown in the code snippet below.

  private IMemoryCache cache;
  public IDGCacheController(IMemoryCache cache)
        {
            this.cache = cache;
        }

And that’s all you need to do to set up support for in-memory caching in your ASP.Net Core application. In the section that follows, we will look at how we can work with the cache API in ASP.Net Core to store and retrieve objects.

How to store and retrieve objects using ASP.Net Core IMemoryCache

To store an object using the IMemoryCache interface you need to use the Set<T>() method as shown in the code snippet below. Note that the version of the Set<T>() method we have used in this example accepts two parameters. The first parameter is the name of the key and the second parameter is the value, i.e., the object that is to be stored in the cache that can be identified using the key.

[HttpGet]
        public string Get()
        {
            cache.Set(“IDGKey”, DateTime.Now.ToString());
            return “This is a test method...”;
        }

To retrieve an item from the cache, you can take advantage of the Get<T>() method as shown below.

  [HttpGet(“{key}”)]
        public string Get(string key)
        {
            return cache.Get<string>(key);
        }

You can use the TryGet() method on the cache object to check if the specified key exists in the cache. Here is the modified version of our Get method that illustrates how this can be achieved.

 [HttpGet]
        public string Get()
        {
            string key ="IDGKey";
            string obj;
            if (!cache.TryGetValue<string>(key, out obj))
            {
                obj = DateTime.Now.ToString();
                cache.Set<string>(key, obj);
            }
            return obj;
        }

There is another method, called GetOrCreate, that can be used to retrieve cached data based on the key provided. If the key doesn’t exist, the method creates it.

[HttpGet]
        public string Get()
        {
            return cache.GetOrCreate<string>(“IDGKey”,
                cacheEntry => {
                            return DateTime.Now.ToString();
                         });
        }

Note that an asynchronous version of this method is available called GetOrCreateAsync. Here is the complete code listing of our IDGCacheController class for your reference.

using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;

namespace InMemoryCaching.Controllers
{
    [Route(“api/[controller]”)]
    public class IDGCacheController : Controller
    {
        private IMemoryCache cache;
        public IDGCacheController(IMemoryCache cache)
        {
            this.cache = cache;
        }

        [HttpGet]
        public string Get()
        {
            return cache.GetOrCreate<string>(“IDGKey”,
                cacheEntry => {
                            return DateTime.Now.ToString();
                         });
        }
    }
}

How to set expiration policies on cached data in ASP.Net Core

Note that you can set absolute and sliding expiration policies on your cached data. While the former is used to specify the duration for which an object should reside in the cache, the latter is used to specify the duration for which an object will reside in the cache when there is no activity—i.e., the item will be removed from the cache when the specified duration of inactivity elapses.

To set expiration policies you use the MemoryCacheEntryOptions class as shown in the code snippet below.

MemoryCacheEntryOptions cacheExpirationOptions = new MemoryCacheEntryOptions();
cacheExpirationOptions.AbsoluteExpiration = DateTime.Now.AddMinutes(30);
cacheExpirationOptions.Priority = CacheItemPriority.Normal;
cache.Set<string>(“IDGKey”, DateTime.Now.ToString(), cacheExpirationOptions);

Note the usage of the Priority property on the MemoryCacheEntryOptions instance in the code snippet above. The Priority property specifies which objects (based on the priority already set) should be removed from the cache as part of a strategy of the runtime to reclaim memory whenever the web server runs out of memory space.

To set the priority, we used the CacheItemPriority enum. This can have one of these possible values: Low, Normal, High, and NeverRemove. The in-memory cache provider in ASP.Net Core will remove cache entries when under memory pressure unless you have set the cache priority to CacheItemPriority.NeverRemove.

You may also want to register a callback that will execute whenever an item is removed from the cache. The following code snippet illustrates how this can be achieved.

cacheExpirationOptions.RegisterPostEvictionCallback 
(IDGCacheItemChangedHandler, this);

You can even set dependencies between the cached objects. As an example, you might want to remove certain items from the cache if some related item has been removed. We will explore this further and many other features of caching in ASP.Net Core in my future posts here. Until then, you may want to take a look at the relevant pages in Microsoft’s ASP.Net Core documentation