Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Adding cache to MediatR
public class CachePipelineBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
private readonly IDistributedCache cache;
private readonly ILogger<SGUKAspNetCore> logger;
public CachePipelineBehavior(
IDistributedCache cache,
ILogger<SGUKAspNetCore> logger)
{
Ensure.Argument.NotNull(cache, nameof(cache));
Ensure.Argument.NotNull(logger, nameof(logger));
this.cache = cache;
this.logger = logger;
}
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
if (request is ICacheable cacheableRequest)
{
var key = cacheableRequest.GetCacheKey();
return await cache.GetOrSet(
key,
miss: () => { Log.CacheMiss(logger, key); return next(); },
hit: (data) => Log.CacheHit(logger, key),
cacheableRequest.GetExpirationTime(),
cancellationToken);
}
var response = await next();
if (request is ICacheableInvalidation cacheInvalidationRequest)
{
foreach (var key in cacheInvalidationRequest.GetCacheKeys())
{
await cache.Remove(key, cancellationToken);
}
}
return response;
}
}
public interface ICacheable
{
public string GetCacheKey();
public TimeSpan? GetExpirationTime() => null;
}
public interface ICacheableInvalidation
{
public IEnumerable<string> GetCacheKeys();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment