# Using Redis for caching in Asp.Net Core

In this previous [article](https://blog.jhonatanoliveira.dev/using-caching-in-aspnet-core-minimal-apis), we learned about caching in Asp.Net Core. We talked about In-Memory cache and Distributed cache using SQL Server cache.

This article will discuss how to use Redis for caching in Asp.Net Core.

# What is Redis?

Redis (**RE**mote **DI**ctionary **S**erver) is an open-source, high-performance, in-memory that allows us to store and retrieve data in our applications.

Used primarily as a database, cache, or message broker, it also supports several data structures such as hashes, lists, sets, sorted sets, bitmaps and others.

# Azure Cache for Redis

Azure Cache for Redis provides an in-memory data store based on the Redis software. Redis improves the performance and scalability of an application that uses backend data stores heavily. It can process large volumes of application requests by keeping frequently accessed data in the server memory, which can be written to and read from quickly.

Azure Cache for Redis can be deployed as a standalone or with other Azure database services, such as Azure SQL or Azure Cosmos DB.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1676742308238/c47418f2-c04f-4495-9a98-1b85eea442d1.png align="center")

## Configure Azure Cache for Redis

To create a new Azure Cache for Redis, first, we need to sign in to the [Azure portal](https://portal.azure.com/). You can create one for [free](https://azure.microsoft.com/en-us/free/) if you don't have an account. After that, click on **Create a resource** and then **Compute.** You should see the item **Azure Cache for Redis.** The following image shows what you should see.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1676743580138/93b6c617-598c-48bb-b195-471350461c81.png align="center")

In the **New Redis Cache** page, we need to specify the subscription plan, the resource group, the DNS name, the server location for using Redis, and the cache type. Please feel free to use the following image for reference.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1676743708234/80e8ea5e-1ec5-4a90-97fc-732af637f75d.png align="center")

In the **Advanced** tab, we can define the Redis version to be used. After that, we can click on **Review + Create** to create the Redis resource in Azure.

# Implementation

First, we need to install the NuGet package [Microsoft.Extensions.Caching.StackExchangeRedis](https://www.nuget.org/packages/Microsoft.Extensions.Caching.StackExchangeRedis), and then we can register the Redis in our services.

```csharp
builder.Services.AddStackExchangeRedisCache(opt =>
{
    opt.Configuration = builder.Configuration.GetConnectionString("Redis");
});
```

We will need the string connection of the Redis in Azure. We need to access the resource and click on the link for **Access Keys**, the image below shows where you can find the links.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1676763056311/3a463996-9f5e-42ee-8a09-080f180fdf5f.png align="center")

The next step is to define the connection string in the `appsettings.json` file.

```json
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost\\MSSQLSERVER01; Database=CoachPlan; Trusted_Connection=True; MultipleActiveResultSets=true",
    "Redis": "Add the Primary connection string here."
  },
```

Now, we are going to change the implementation of our services. The package that we are using contains the implementation of the `IDistributedCache` interface so that we can inject this interface into our services.

```csharp
    private readonly IMuscleRepository _muscleRepository;
    private readonly IDistributedCache _distributedCache;
    private readonly JsonSerializerSettings _jsonSerializerSettings;

    public MuscleService(IMuscleRepository muscleRepository, IDistributedCache distributedCache)
    {
        _muscleRepository = muscleRepository;
        _distributedCache = distributedCache;

        _jsonSerializerSettings = new()
        {
            ReferenceLoopHandling = ReferenceLoopHandling.Ignore
        };
    }
```

The following code shows the implementation of the `GetById` method. So, before going to the database to get the data, we verify if it is cached and then return it; otherwise, the data will be fetched from the database and cached.

To get the cached data, we need to use the method `GetStringAsync` which will return the `Json` of the cached data if it exists.

To send the data to Redis, we use the method `SetStringAsync,` which uses the data we want to cache as a parameter.

```csharp
    public async Task<GetMuscleDto> GetById(int id)
    {
        string key = $"muscle-{id}";

        string cachedMuscle = await _distributedCache.GetStringAsync(key);

        Muscle muscle = null;

        if (string.IsNullOrEmpty(cachedMuscle))
        {
            muscle = await _muscleRepository.GetById(id);

            if (muscle is not null)
            {
                await _distributedCache.SetStringAsync(key, JsonConvert.SerializeObject(muscle, _jsonSerializerSettings));
            }
        }
        else
        {
            muscle = JsonConvert.DeserializeObject<Muscle>(cachedMuscle);
        }

        return muscle.ToGetDto();
    }
```

In case we want to use the cache expiration, we have two options:

1. Absolute expiration means no matter the frequency of accessing cached data, and it will be removed after a fixed time.
    
2. Sliding expiration provides a way to remove the cached data which are not frequently accessed. If an object's sliding expiration of 30 seconds is enabled, it will expire only if the data was not accessed in the last 30 seconds.
    

We can create an instance of `DistributedCacheEntryOptions` and define the type of cache expiration we want to use. The following code shows how to create and use the instance in the method `SetStringAsync`.

```csharp
 var expiration = new DistributedCacheEntryOptions
 {
    AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(30),
    SlidingExpiration = TimeSpan.FromSeconds(25)
 };

 await _distributedCache.SetStringAsync(key, JsonConvert.SerializeObject(muscles, _jsonSerializerSettings), expiration);
```

# **Wrapping Up**

If you don't need more Azure Cache for Redis, remember to delete it in the Azure Portal.

You can find the complete code on my [**GitHub**](https://github.com/jhonatanfernando/coachplan).
