Popular Posts

May 14, 2024

In-Memory Caching in ASP.NET Core

 


 

In ASP.NET Core, in-memory caching is a technique used to store data within the application's memory. This cached data is readily accessible to subsequent requests, which can significantly improve the performance of the application by avoiding expensive operations such as repeated database queries or complex calculations.

 

Create an webapi project named it InMemoryCaching. We will use database first approach.

In appsetting set database configutation:

,

  "ConnectionStrings": {

    "DBConnectionString": "Server=DESKTOP-M80VO7A;Database=EmployeeDB;Trusted_Connection=True;MultipleActiveResultSets=true; TrustServerCertificate=True;Integrated Security=SSPI; TrustServerCertificate=True; MultipleActiveResultSets=true;"

  }

 

 

Create context file: EmployeeDbContext

public partial class EmployeeDbContext : DbContext

{

   

    public EmployeeDbContext(DbContextOptions<EmployeeDbContext> options)

        : base(options)

    {

    }

}

In Program.cs file:

builder.Services.AddDbContext<EmployeeDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DBConnectionString")));

 

builder.Services.AddMemoryCache();

 

we need to download some nuget packages like SqlServer, Tools, Design etc.


 

Open package manager console and run the command:

Scaffold-DbContext -Connection Name=DBConnectionString Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models –force

 

Create controller named it EmployeeController

Write the code below in the controller:

 

private readonly EmployeeDbContext _context;

private readonly IMemoryCache _cache;

 

 

public EmployeeController(EmployeeDbContext context, IMemoryCache cache)

{

    _context = context;

    _cache = cache;

}

 

[HttpGet]

public async Task<IActionResult> GetAll()

{

    var products = await _context.Employees.ToListAsync();

 

    return Ok(products);

}

 

[HttpGet]

[Route("GetAllCache")]

public async Task<IActionResult> GetAllCache()

{

    var cacheKey = "GET_ALL_EMPLOYEES";

 

    // If data found in cache, return cached data

    if (_cache.TryGetValue(cacheKey, out List<Employee> Employees))

    {

        return Ok(Employees);

    }

 

    // If not found, then fetch data from database

    Employees = await _context.Employees.ToListAsync();

 

    // Add data in cache

    _cache.Set(cacheKey, Employees);

 

    return Ok(Employees);

}

 

 

Open post man and test the controller, when we run get all we get the result below:


 

 

 

When we run get all cache:


 

To cache data for the exact time, we can use the AbsoluteExpiration setting. In the following code snippet, the AbsoluteExpiration is set to 5 minutes, which means no matter how frequently our cached data is accessed, it will flush after 5 minutes.

            var cacheOptions = new MemoryCacheEntryOptions()

            {

                AbsoluteExpiration = DateTime.Now.AddMinutes(5)

            };

 

            _cache.Set(cacheKey, Employees, cacheOptions);

 

We can also use the SlidingExpiration setting which allows us to remove cached items which are not frequently accessed. In the example below, I set it to 5 minutes which means that data will remove from the cache only if it is not accessed in the last 5 minutes.

            var cacheOptions = new MemoryCacheEntryOptions()

            {

                SlidingExpiration = TimeSpan.FromMinutes(5)

            };

 

            _cache.Set(cacheKey, Employees, cacheOptions);

 

If our data is accessed more frequently than our sliding expiration time, then we will end up in a situation where our data will never expire. We can resolve this problem by following code:

            var cacheOptions = new MemoryCacheEntryOptions()

            {

                SlidingExpiration = TimeSpan.FromMinutes(5),

                AbsoluteExpiration = DateTime.Now.AddMinutes(60)

            };

 

            _cache.Set(cacheKey, Employees, cacheOptions);

 

 

 

We can also set the priority of the cached items to keep high priority items in cache during a memory pressure triggered cleanup. By default, all items in the cache have Normal priority but we are allowed to set Low, Normal, High, and NeverRemove options as well.

 

var cacheOptions = new MemoryCacheEntryOptions()

{

    AbsoluteExpiration = DateTime.Now.AddMinutes(60),

    Priority = CacheItemPriority.High

};

 

_cache.Set(cacheKey, Employees, cacheOptions);




Github: https://github.com/itsjubayer/InMemoryCaching.git

No comments:

Post a Comment