using EasyCaching.Core; using MediatR; using Microsoft.Extensions.Logging; namespace BuildingBlocks.Caching; public class CachingBehavior : IPipelineBehavior where TRequest : notnull, IRequest where TResponse : notnull { private readonly ICacheRequest _cacheRequest; private readonly IEasyCachingProvider _cachingProvider; private readonly ILogger> _logger; private readonly int defaultCacheExpirationInHours = 1; public CachingBehavior(IEasyCachingProviderFactory cachingFactory, ILogger> logger, ICacheRequest cacheRequest) { _logger = logger; _cachingProvider = cachingFactory.GetCachingProvider("mem"); _cacheRequest = cacheRequest; } public async Task Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate next) { if (request is not ICacheRequest || _cacheRequest == null) // No cache request found, so just continue through the pipeline return await next(); var cacheKey = _cacheRequest.CacheKey; var cachedResponse = await _cachingProvider.GetAsync(cacheKey); if (cachedResponse.Value != null) { _logger.LogDebug("Response retrieved {TRequest} from cache. CacheKey: {CacheKey}", typeof(TRequest).FullName, cacheKey); return cachedResponse.Value; } var response = await next(); var expirationTime = _cacheRequest.AbsoluteExpirationRelativeToNow ?? DateTime.Now.AddHours(defaultCacheExpirationInHours); await _cachingProvider.SetAsync(cacheKey, response, expirationTime.TimeOfDay); _logger.LogDebug("Caching response for {TRequest} with cache key: {CacheKey}", typeof(TRequest).FullName, cacheKey); return response; } }