Есть ли способ пропустить трубопровод MediatR? - PullRequest
0 голосов
/ 24 апреля 2020

Я бы хотел кешировать некоторые ответы от CommandsHandlers.

Я уже сделал это, используя IPipelineBehaviour, но только 5% моих запросов действительно должны иметь кеш, а остальные 95% должны пропустить этот конвейер. Есть ли способ сделать это?

Ниже следует мой код.

Спасибо!

     public class PipelineBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> 
                                         where TRequest : IRequest<TResponse>, IProvideCacheKey
    {
        private readonly IMemoryCache _cache;
        public PipelineBehavior(IMemoryCache cache)
        {
            _cache = cache;
        }
        public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, 
                                            RequestHandlerDelegate<TResponse> next)
        {
            // Check in cache if we already have what we're looking for
            var cacheKey = request.CacheKey;
            if (_cache.TryGetValue<TResponse>(cacheKey, out var cachedResponse))
            {
                return cachedResponse;
            }
            // If we don't, execute the rest of the pipeline, and add the result to the cache
            var response = await next();
            _cache.Set(cacheKey, response);
            return response;
        }
    }





     public class GetUserByEmailCommand : Command, IRequest<bool>, IProvideCacheKey
     {
        public string Email { get; set; }

        public string CacheKey =>  $"{GetType().Name}:{Email}";

        public override bool IsValid()
        {
            ValidationResult = new GetUserByEmailCommandValidation<GetUserByEmailCommand>().Validate(this);

            return ValidationResult.IsValid;
        }
    }



  public interface IProvideCacheKey
  {
        string CacheKey { get; }
  }

1 Ответ

1 голос
/ 25 апреля 2020

Вы можете свернуть свое поведение кэширования в проверку, которая обойдется, если запрос не кэшируется, чтобы позволить конвейеру продолжить. В вашем случае вы, вероятно, можете просто проверить, реализует ли запрос ваш интерфейс в начале метода Handle:

if (request is IProvideCacheKey)
{
   // perform cache behavior, return if cached and terminate the pipeline
}
// else continue the pipeline

Есть несколько хороших примеров этого более подробно:

https://lurumad.github.io/cross-cutting-concerns-in-asp-net-core-with-meaditr

https://anderly.com/2019/12/12/cross-cutting-concerns-with-mediatr-pipeline-behaviors/

...