Caching Strategies in .NET Core


19 July 2018

In today’s web development, performance is a critical factor for delivering fast and reliable applications. One of the most effective ways to boost performance is through caching. Caching helps by storing frequently accessed data temporarily, so it can be quickly retrieved without the need to recompute or fetch it from a data source repeatedly. In this post, we’ll explore how caching works in .NET Core and review various caching strategies, including in-memory caching and distributed caching with Redis and SQL Server.


In-Memory Caching for Web API Performance

In-memory caching stores data directly in the memory of your application, which is the fastest and most efficient form of caching. It’s particularly useful when you need to store small, frequently accessed data that doesn’t change often, such as configuration settings or lookup values.

Setting Up In-Memory Caching in .NET Core

To get started with in-memory caching in .NET Core, you’ll need to add the Microsoft.Extensions.Caching.Memory package to your project.

Step 1: Install the Necessary Package

dotnet add package Microsoft.Extensions.Caching.Memory

Step 2: Configure the Caching Service in Startup.cs

In the ConfigureServices method of your Startup.cs, add the following code to configure in-memory caching:

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

This adds the in-memory cache service to the DI container.

Step 3: Using In-Memory Cache in Your Controllers

You can now use the cache in your controller or service. Here’s an example of how to use the cache to store and retrieve data:

public class ProductController : ControllerBase
{
    private readonly IMemoryCache _memoryCache;
    private readonly IProductService _productService;

    public ProductController(IMemoryCache memoryCache, IProductService productService)
    {
        _memoryCache = memoryCache;
        _productService = productService;
    }

    [HttpGet]
    public IActionResult GetProducts()
    {
        string cacheKey = "products";
        List<Product> products;

        // Try to get the data from the cache
        if (!_memoryCache.TryGetValue(cacheKey, out products))
        {
            // If not found in cache, fetch from the service
            products = _productService.GetProducts();

            // Set data in the cache with an expiration time
            _memoryCache.Set(cacheKey, products, TimeSpan.FromMinutes(5));
        }

        return Ok(products);
    }
}

In this example, we first attempt to retrieve the list of products from the cache using the TryGetValue method. If the data is not in the cache, we retrieve it from the database (via the IProductService) and store it in the cache for later use.


Distributed Caching with Redis

While in-memory caching is fast, it’s limited to the lifespan of the application instance. When your application is running in a distributed environment, such as a load-balanced scenario with multiple instances of your application, you’ll need a distributed cache. Redis is a popular choice for distributed caching in .NET Core.

Redis allows you to store data outside the application, making it accessible from any instance, ensuring consistency and availability across multiple servers.

Setting Up Redis Caching in .NET Core

Step 1: Install the Redis Package

To use Redis as a distributed cache, you’ll need to add the Microsoft.Extensions.Caching.StackExchangeRedis package:

dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis

Step 2: Configure Redis in Startup.cs

In ConfigureServices, configure Redis caching:

public void ConfigureServices(IServiceCollection services)
{
    services.AddStackExchangeRedisCache(options =>
    {
        options.Configuration = "localhost"; // or your Redis server address
        options.InstanceName = "SampleApp_";
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Here, we’re configuring the Redis server. Replace "localhost" with your Redis server’s address if it’s hosted elsewhere.

Step 3: Using Redis Cache in Your Controllers

Once Redis is set up, you can use it in your controller in the same way as in-memory caching. Here’s an example:

public class ProductController : ControllerBase
{
    private readonly IDistributedCache _distributedCache;
    private readonly IProductService _productService;

    public ProductController(IDistributedCache distributedCache, IProductService productService)
    {
        _distributedCache = distributedCache;
        _productService = productService;
    }

    [HttpGet]
    public async Task<IActionResult> GetProducts()
    {
        string cacheKey = "products";
        List<Product> products;

        // Try to get the data from the cache
        var cachedProducts = await _distributedCache.GetStringAsync(cacheKey);

        if (string.IsNullOrEmpty(cachedProducts))
        {
            // If not found in cache, fetch from the service
            products = _productService.GetProducts();

            // Set data in the cache with an expiration time
            var options = new DistributedCacheEntryOptions()
                .SetAbsoluteExpiration(TimeSpan.FromMinutes(5));

            await _distributedCache.SetStringAsync(cacheKey, JsonConvert.SerializeObject(products), options);
        }
        else
        {
            products = JsonConvert.DeserializeObject<List<Product>>(cachedProducts);
        }

        return Ok(products);
    }
}

In this example, we use the IDistributedCache interface to interact with Redis. If the products are not found in the cache, we fetch them from the database and store them in Redis.


Distributed Caching with SQL Server

SQL Server can also be used as a distributed cache for .NET Core applications. This can be useful if you already have SQL Server as your database and don’t want to introduce an additional dependency like Redis.

Setting Up SQL Server for Caching

Step 1: Install the SQL Server Cache Provider Package

To use SQL Server as a distributed cache, you’ll need to add the Microsoft.Extensions.Caching.SqlServer package:

dotnet add package Microsoft.Extensions.Caching.SqlServer

Step 2: Configure SQL Server in Startup.cs

Configure the SQL Server cache in ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSqlServerCache(options =>
    {
        options.ConnectionString = "YourConnectionStringHere";
        options.SchemaName = "dbo";
        options.TableName = "Cache";
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Here, we specify the connection string to SQL Server, along with the schema and table name for storing cache data.

Step 3: Using SQL Server Cache

You can use the SQL Server cache in the same way as Redis, using the IDistributedCache interface. The usage in the controller is similar to the Redis example.


Conclusion

Caching is a critical technique to improve the performance of your .NET Core applications. Whether you’re using in-memory caching, Redis, or SQL Server, it’s important to understand when and how to use each type of cache.

  • In-Memory Caching: Best for single-instance applications or small, frequently accessed data.
  • Redis (Distributed Caching): Ideal for multi-instance, distributed applications.
  • SQL Server (Distributed Caching): Useful if you’re already using SQL Server and want to avoid additional dependencies.

By using the right caching strategy, you can significantly improve your application’s speed and responsiveness.

In the next post, we’ll continue exploring more advanced .NET Core topics. Stay tuned!


Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *