NexGen.MediatR.Extensions.Caching
1.0.6
dotnet add package NexGen.MediatR.Extensions.Caching --version 1.0.6
NuGet\Install-Package NexGen.MediatR.Extensions.Caching -Version 1.0.6
<PackageReference Include="NexGen.MediatR.Extensions.Caching" Version="1.0.6" />
<PackageVersion Include="NexGen.MediatR.Extensions.Caching" Version="1.0.6" />
<PackageReference Include="NexGen.MediatR.Extensions.Caching" />
paket add NexGen.MediatR.Extensions.Caching --version 1.0.6
#r "nuget: NexGen.MediatR.Extensions.Caching, 1.0.6"
#:package NexGen.MediatR.Extensions.Caching@1.0.6
#addin nuget:?package=NexGen.MediatR.Extensions.Caching&version=1.0.6
#tool nuget:?package=NexGen.MediatR.Extensions.Caching&version=1.0.6
β‘ NexGen.MediatR.Extensions.Caching
A lightweight and flexible library that extends MediatR to provide seamless caching and cache invalidation for requests using pipeline behaviors in .NET applications.
This library integrates caching as a cross-cutting concern, enabling developers to cache query results π and invalidate caches efficiently within the MediatR pipeline, improving application performance and scalability.
π Table of Contents
β¨ Features
- Seamless Integration: Adds caching to MediatR requests using pipeline behaviors.
- Flexible Cache Storage: Supports both in-memory (
IMemoryCache
) πΎ and distributed caching (IDistributedCache
) π. - Automatic Cache Invalidation: Invalidate cached requests based on other requests or notifications.
- Customizable Cache Options: Configure expiration β³, sliding expiration, and cache keys per request.
- ASP.NET Core Compatibility: Works with ASP.NET Coreβs DI and caching infrastructure.
- Extensible Design: Easily extend or customize caching behavior to suit your needs.
π¦ Installation
You can install NexGen.MediatR.Extensions.Caching
via NuGet Package Manager or the .NET CLI.
Using NuGet Package Manager
Install-Package NexGen.MediatR.Extensions.Caching
Using .NET CLI
dotnet add package NexGen.MediatR.Extensions.Caching
βοΈ Configuration
Step 1: Configure MediatR and Caching Services
In your Startup.cs
or Program.cs
, register MediatR and caching:
Using
MemoryCache
builder.Services.AddMediatROutputCache(opt => { opt.UseMemoryCache(); });
Using
Redis
(NexGen.MediatR.Extensions.Caching.Redis
)builder.Services.AddMediatROutputCache(opt => { var redisConnectionString = "localhost:6379,password=YourPassword"; opt.UseRedisCache(redisConnectionString); });
Step 2: Using Caching Services
Add RequestOutputCache
attribute to your IRequest
class:
The request class must implement IRequest<Response>
where Response
is not an interface!
[RequestOutputCache(tags: ["weather"], expirationInSeconds: 300)]
public class WeatherForecastRequest : IRequest<IEnumerable<WeatherForecastDto>>
{
public int Limit { get; set; } = 10;
public int Offset { get; set; } = 0;
}
Step 3: Invalidate Cached Responses
Invalidate cached responses by tags:
public class TestClass
{
private readonly IRequestOutputCache<WeatherForecastEvictRequest, string> _cache;
public TestClass(IRequestOutputCache<WeatherForecastEvictRequest, string> cache)
{
_cache = cache;
}
public async Task EvictWeatherResponses()
{
List<string> tags = [ "weather" ];
await _cache.EvictByTagsAsync(tags);
}
}
π‘ Examples
Example 1: Caching a List of Items
Suppose you have a query to fetch a list of Weather Forecasts:
[RequestOutputCache(tags: ["weather"], expirationInSeconds: 300)]
public class WeatherForecastRequest : IRequest<IEnumerable<WeatherForecastDto>>
{
public int Limit { get; set; } = 10;
public int Offset { get; set; } = 0;
}
public class WeatherForecastRequestHandler : IRequestHandler<WeatherForecastRequest, IEnumerable<WeatherForecastDto>>
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
public async Task<IEnumerable<WeatherForecastDto>> Handle(WeatherForecastRequest request, CancellationToken cancellationToken)
{
await Task.Delay(2000, cancellationToken);
return Enumerable.Range(1, request.Limit).Select(index => new WeatherForecastDto
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
}).ToArray();
}
}
The response will be cached with the key "weather"
for 5 minutes.
If expirationInSeconds
is not provided, it uses the default value. To make the response never expire, set expirationInSeconds
to Zero.
Example 2: Invalidation on Update
When a response must be updated, invalidate the product list cache:
public class WeatherForecastUpdateRequest : IRequest<string>
{
}
public class WeatherForecastUpdateRequestHandler : IRequestHandler<WeatherForecastUpdateRequest, string>
{
private readonly IRequestOutputCache<WeatherForecastUpdateRequest, string> _cache;
public WeatherForecastUpdateRequestHandler(IRequestOutputCache<WeatherForecastUpdateRequest, string> cache)
{
_cache = cache;
}
public async Task<string> Handle(WeatherForecastUpdateRequest request, CancellationToken cancellationToken)
{
var tags = new List<string> { nameof(WeatherForecastDto) };
await _cache.EvictByTagsAsync(tags, cancellationToken);
return "Evicted!";
}
}
See Integration Test in test folder to see for example.
π Benchmarks
This benchmark is available in benchmark directory (NexGen.MediatR.Extensions.Caching.Benchmark
).
This is benchmark results of testing same simple request with and without caching using NexGen.MediatR.Extensions.Caching
package.
The bigger and complicated responses may use more allocated memory in memory cache solution.
Better to use distributed cache services like Redis
in enterprise projects.
π€ Contributing
Contributions are welcome! To contribute to NexGen.MediatR.Extensions.Caching
:
- Fork the repository.
- Create a new branch (
git checkout -b feature/your-feature
). - Make your changes and commit them (
git commit -m "Add your feature"
). - Push to the branch (
git push origin feature/your-feature
). - Open a pull request.
Please ensure your code follows the project's coding standards and includes unit tests where applicable.
π License
This project is licensed under the MIT License. See the LICENSE file for details.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- FluentResults (>= 4.0.0)
- MediatR (>= 13.0.0)
- Microsoft.Extensions.Caching.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Caching.Memory (>= 8.0.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Newtonsoft.Json (>= 13.0.3)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on NexGen.MediatR.Extensions.Caching:
Package | Downloads |
---|---|
NexGen.MediatR.Extensions.Caching.Redis
NexGen.MediatR.Extensions.Caching.Redis |
|
NexGen.MediatR.Extensions.Caching.Garnet
NexGen.MediatR.Extensions.Caching.Garnet |
GitHub repositories
This package is not used by any popular GitHub repositories.
Release v1.0.6