Skip to content

Instantly share code, notes, and snippets.

Last active Dec 12, 2019
What would you like to do?
MediatR Fallback Pipeline Behavior
public class Handler : IRequestHandler<Query, Customer>, IFallbackHandler<Query, Customer>
private readonly ICustomerRepository _db;
private readonly ICustomerRepository<SourceSystem.Secondary> _db2;
private readonly IConfigurationProvider _configuration;
public Handler(ICustomerRepository db, ICustomerRepository<SourceSystem.Secondary> db2, IConfigurationProvider configuration)
_db = db;
_db2 = db2;
_configuration = configuration;
public async Task<Customer> Handle(Query message, CancellationToken token)
return await _db.GetCustomerByNumberAsync(message.CustomerNumber);
// HandleFallback method from IFallbackHandler<TRequest, TResponse> interface.
// This method will get called if my Handle method fails.
public async Task<Customer> HandleFallback(Query message, CancellationToken token)
return await _db2.GetCustomerByNumberAsync(message.CustomerNumber);
/// <summary>
/// MediatR Fallback Pipeline Behavior
/// </summary>
/// <typeparam name="TRequest"></typeparam>
/// <typeparam name="TResponse"></typeparam>
public class FallbackBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
private readonly IEnumerable<IFallbackHandler<TRequest, TResponse>> _fallbackHandlers;
private readonly ILogger<FallbackBehavior<TRequest, TResponse>> _logger;
public FallbackBehavior(IEnumerable<IFallbackHandler<TRequest, TResponse>> fallbackHandlers, ILogger<FallbackBehavior<TRequest, TResponse>> logger)
_fallbackHandlers = fallbackHandlers;
_logger = logger;
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
var fallbackHandler = _fallbackHandlers.FirstOrDefault();
if (fallbackHandler == null)
// No fallback handler found, continue through pipeline
return await next();
var fallbackPolicy = Policy<TResponse>
.FallbackAsync(async (cancellationToken) =>
_logger.LogDebug($"Initial handler failed. Falling back to `{fallbackHandler.GetType().FullName}@HandleFallback`");
return await fallbackHandler.HandleFallback(request, cancellationToken)
var response = await fallbackPolicy.ExecuteAsync(async () => await next());
return response;
public interface IFallbackHandler<TRequest, TResponse> where TRequest : IRequest<TResponse>
Task<TResponse> HandleFallback(TRequest request, CancellationToken cancellationToken);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment