How To Use Azure Redis Cache In C#

Introduction

Azure Redis Cache is based on open source, in-memory Redis Cache that allows Web apps to bring data from a backend data source into cache and server Web pages from the cache to improve app performance. In this step by step tutorial, we will learn how to use Azure Redis Cache in our Web app.

What is Azure Redis Cache?

Modern applications mostly work with a large amount of data. In this scenario, when you retrieve data from a database, it typically finds the table and gets the results that it sends back to the user. The performance, in such case, goes down due to multiple requests. So, to reduce some number of requests, you can use cache data that does not change frequently.

Redis Cache is an open source,in-memory database that is used for improving the performance of an application by retrieving and storing the data in the cache memory using a Key-value format.Azure Redis Cache is a feature-rich functionality that gives you access to secure, low-latency, high-performance throughput.

Let’s start Redis Cache implementation with C#.

Step 1. Log into Azure port, go to Databases >> Redis Cache.

Microsoft Azure Database-

Step 2. Create a news Redis Cache.

Microsoft Azure Create-

Step 3. Get the Access Keys to connect with the newly created Redis Cache.

Azure Redis Cache In C#

Install the StackExchange.Redis

Step 4. Install the StackExchange.Redis NuGet package using the following command.

Install-Package StackExchange.Redis

Stack Exchange Redis-

Let’s start coding to store the data into Redis Cache and retrieve the data from Redis Cache. We had recently seen the code of Azure Document DB CRUD operations. If you have not read it yet, click on Azure Document DB CRUD Operation and read. We have the code of CRUD operations in Document DB. Now, we will implement Redis Cache here.

Step 5. Similar to the previous article, we need to add Redis Cache connection string into the appsettings.dev.json file.

Schema-.jpg

Step 6. Now, add one more property RedisCache into Config.cs that will get the value of Redis Cache connection string from appsettings.dev.json.

public class Config
{
    public DocDbConnectionString docDb { get; set; }
    public string RedisCache { get; set; }
}`
public class DocDbConnectionString
{
    public string EndPoint { get; set; }
    public string AuthKey { get; set; }
    public string Database { get; set; }
    public string Collection { get; set; }
}

Step 7. Let’s come to the program.cs file and add ConnectionMultiplexer for Redis Cache.

IDatabase cache = lazyConnection.Value.GetDatabase();
private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
    string cacheConnection = configs.RedisCache;
    return ConnectionMultiplexer.Connect(cacheConnection);
});
public static ConnectionMultiplexer Connection
{
    get
    {
        return lazyConnection.Value;
    }
}

Now, we will store a document into Redis Cache on the basis of Key while creating a document into Document DB and while reading this document, we will use the Key to check if the document is present in Redis Cache or not. We will skip reading the document further from Document DB. By doing this, we can increase the performance of the application.

var collection = UriFactory.CreateDocumentCollectionUri(configs.docDb.Database, configs.docDb.Collection);
try
{
    // create JObject which contains the employee details
    Console.WriteLine("\nCreating document");
    JObject emp = new JObject();
    emp.Add("id", "V003");
    emp.Add("name", "virendra");
    emp.Add("address", "Indore");
    emp.Add("Country", "India");

    // create the document into DocumentDb
    var createResponse = await Client.CreateDocumentAsync(collection, emp);
    var createdDocument = createResponse.Resource;

    Console.WriteLine("Document with id {0} created", createdDocument.Id);
    // Set JObject into redis cache with key "redisEmp3"
    var entryInRedis = await cache.StringSetAsync("redisEmp3", emp.ToString());
    Console.WriteLine("Document with key redisEmp3 stored into redis cache");
}
catch (Exception ex)
{
    throw ex;
}

Step 8. Instead, let us read the document from Redis Cache.

// Read document from Redis Cache.
var empInRedis = await cache.StringGetAsync("redisEmp3");
if (!empInRedis.IsNullOrEmpty)
{
    Console.WriteLine("Read Document from RedisCache {0} : ", empInRedis);
}

// If Redis Cache does not have Document, then read the document from Document DB
if (empInRedis.IsNullOrEmpty)
{
    var readResponse = await client.ReadDocumentAsync(UriFactory.CreateDocumentUri(configs.docDb.Database, configs.docDb.Collection, "V001"));
    var readDocument = readResponse.Resource;
    Console.WriteLine("Read Document {0}: ", readResponse.Resource.ToString());
}

The below snapshot shows how we read a document from Redis Cache.

Azure Redis Cache 6-

Step 10. The following is the whole code of the Program.cs class.

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
using StackExchange.Redis;
using Microsoft.Azure.Documents.Client;

public class Program
{
    private static IConfiguration Configuration { get; set; }
    private static Config configs;
    private DocumentClient client;
    private IDatabase cache = lazyConnection.Value.GetDatabase();

    static void Main(string[] args)
    {
        // Set up Configuration
        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: false, reloadOnChange: true);
        Configuration = builder.Build();
        configs = new Config();
        Configuration.Bind(configs);

        Program obj = new Program();
        obj.CRUDOperation().Wait();
    }

    // CRUD Operation
    private async Task CRUDOperation()
    {
        var collection = UriFactory.CreateDocumentCollectionUri(configs.docDb.Database, configs.docDb.Collection);
        try
        {
            // create JObject which contains the employee details
            Console.WriteLine("\nCreating document");
            JObject emp = new JObject();
            emp.Add("id", "V003");
            emp.Add("name", "virendra");
            emp.Add("address", "Indore");
            emp.Add("Country", "India");
            // create the document
            var createResponse = await Client.CreateDocumentAsync(collection, emp);
            var createdDocument = createResponse.Resource;

            Console.WriteLine("Document with id {0} created", createdDocument.Id);
            // Set JObject into redis cache with key "redisEmp3"
            var entryInRedis = await cache.StringSetAsync("redisEmp3", emp.ToString());
            Console.WriteLine("Document with key redisEmp3 stored into redis cache");
        }
        catch (Exception ex)
        {
            throw ex;
        }
        // read document from redis cache
        var empInRedis = await cache.StringGetAsync("redisEmp3");
        if (!empInRedis.IsNullOrEmpty)
        {
            Console.WriteLine("Read Document from RedisCache {0} : ", empInRedis);
        }
        if (empInRedis.IsNullOrEmpty)
        {
            // Read document from document Db
            var readResponse = await client.ReadDocumentAsync(UriFactory.CreateDocumentUri(configs.docDb.Database, configs.docDb.Collection, "V001"));
            var readDocument = readResponse.Resource;
            Console.WriteLine("Read Document {0}: ", readResponse.Resource.ToString());
        }

    }

    // Get a single instance of Document client and reuse
    public DocumentClient Client
    {
        get
        {
            if (client == null)
            {
                Uri endpointUri = new Uri(configs.docDb.EndPoint);
                client = new DocumentClient(endpointUri, configs.docDb.AuthKey, null, ConsistencyLevel.Session);
                client.OpenAsync();
            }
            return client;
        }
    }
    // To establish Redis Cache connection
    private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
    {
        string cacheConnection = configs.RedisCache;
        return ConnectionMultiplexer.Connect(cacheConnection);
    });

    public static ConnectionMultiplexer Connection
    {
        get
        {
            return lazyConnection.Value;
        }
    }
}

I hope this article will help you.