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!