Caching in ASP.NET Core MVC and Web API

Caching :- To improve the performance of any application there are many ways to improve it. Caching is one of the way by which we can improve the application performance and optimize the data retrieval from various sources. In Caching we store frequent used data into a local storage called the cache for some interval and when required we serve data from the cache so it will reduce the database operations and provides the quick data to application. It will minimize the database load and improve the response.

Types of Caching in ASP.Net Core

There are mainly three types of caching in ASP.Net core which is listed below :-

  • In-Memory Caching :- Data is stored into the memory of web server and it is relatively fast and simple to implement but it has some limitations of memory in server. It is suitable for using in the lightwight application and chaching is required for single instance of application.
  • Distributed Caching :- As name suggests one common cache shared accross multiple servers. Sharing Cache to multiple servers will reduce the memory requirements in single hosted server and it provides the fast access of cached data and it is widely used in Microservices Architectures where application deployed on more than one server. Now a days SQL Server and Redis is the popular chioces for Distributed Caching in ASP.Net Core.
  • Response Caching :- Response Caching mainly deals with the Response we get from a Http request. Response is Cached in Cache by Response Caching and widely used in Web API and Web Applications.

Below is the image attached for explaining the Caching Process , Here I have used data retrieval using Caching and without Caching. If you are not using the Caching then there may be more DB calls you have to made as shown in below image , here three users are making 3 different calls to fetch Employee Data from database , In that case application has three DB calls for same set of data so that it will increase the processing time and decrease the application performance. In other hand we have implemented the Caching in which we have Stored the Employee data into a Local Storage called as Cache and all the three users are getting data from Stored Cached data so that it will provide the fast access of data from Cache and reduce number of DB Calls.

Image is not available

How to Implement Caching in .NET Core

In Memory Cache Implementation :-

In Memory caching implementation , I have created a interface named ICacheService in which I have declared one GetAsync method is accepting three parameters first is name of cacheKey, Second one is Task and third one is Timespan as you can see in below image.

Image is not available
                    
public interface ICacheService
{
   Task GetAsync(string cacheKey,Task DataRetrieval,TimeSpan? slidingExipartion=null);
}
 

Create a Class InMemoryCachedServices and implement the ICacheService here so that this class has to provide the implementation of GetAsync method. Create a Constructor of this class and assign the private readonly property for IMemoryCache interface in constructor. IMemoryCache is used for caching inbuild methods. Check for already cached data into the cache using the TryGetValue method , if data is not there then we have to fetch data from server and saved into the Cache for some duration that we have to define some parameters with MemoryCacheEntryOptions like timespan for cache. If cached data is exist then it will return data from cache otherwise fetch the data from server and set the data into cache and then return it back to user.

Image is not available
                    
public class InMemoryCachedServices :ICacheService
{
   private readonly IMemoryCache cache;
   public InMemoryCachedServices(IMemoryCache _cache)
   {
        cache = _cache;  
   }
   public async Task GetAsync(string cacheKey, 
                        Task DataRetrieval, 
                        TimeSpan? slidingExipartion = null)
   {
      if(!cache.TryGetValue(cacheKey, out T cachedata))
      {
        cachedata=await DataRetrieval;

        var cacheEntriOptions = new MemoryCacheEntryOptions
        {
          SlidingExpiration= slidingExipartion ?? TimeSpan.FromMinutes(1),
        };
        cache.Set(cacheKey, cachedata, cacheEntriOptions);
     }

     return cachedata;
   }
}
 

For caching we need to add Caching Middileware in applications's Program.cs file. Here I have added AddMemoryCache() middileware and also we have to register the interface and service class that we have written the cache code and we need to inject this services in Employee Controller. Below is the attached code for Program.cs file.

Image is not available
                    
builder.Services.AddMemoryCache();
builder.Services.AddScoped();
 
Image is not available

After registering the services into program.cs file , Now I have created a Employee Controller and inside the controller I have created on constructor for getting dependency objects and services so that we can use them in controller level. Here I have injected ICacheService ,ILogger in constructor. I have created on Action Method GetEmployeeList() for getting the Employee list and return the Employee list in response as shown in below code. Here I have logged httprequests into one logger file so that we can evaluate the caching functionlity in more details.

                    
 public class EmployeeController : ControllerBase
    {
        private readonly IEmployeeRepo _empService;
        private readonly ILogger _logger;       
        private readonly ICacheService _cache;
        public EmployeeController(IEmployeeRepo empService, 
                ILogger logger,
                ICacheService cache)
        {
            _empService = empService;
            _logger = logger;           
            _cache = cache;
        }
        [HttpGet("getemployeelist")]
        public async Task> GetEmployeeList()
        {
            try
            {
               _logger.LogInformation("Requesting Employee List Details...");
               var keyForCache = "employeeList";
               List employeeList= await _cache.GetAsync(keyForCache, _empService.GetEmployeeListAsync(),
                                                                    TimeSpan.FromMinutes(1));
                _logger.LogInformation("Employee List Details fetched...");
                return employeeList;
            }
            catch
            {   throw;
            }
        }
}
 

As shown in below image you can see first request is getting 13 seconds to fetch data from server and Second request is atking only 4 seconds because here it is getting data from cache so that it has lower execution and response time.

Image is not available

Image is not available

About the Author
Sudheer Singh Chouhan is a Software Engineer having Expertise in Development Design and Architecting the applications , Project Management , Designing Large Scale Databases in SQL Server since last 17 Years.
Skill Sets :- Microsoft .NET technologies like ASP.Net Core, Web API, LINQ, Web Forms, WinForms, SQL Server, EntityFramework, Design Patterns, Solid Principles, Microservices, AWS Cloud.