Last active
December 12, 2019 19:52
-
-
Save anderly/576aece4c7c37ce8a6cc1fc5a7f6bb9e to your computer and use it in GitHub Desktop.
MediatR Fallback Pipeline Behavior
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <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> | |
.Handle<Exception>() | |
.FallbackAsync(async (cancellationToken) => | |
{ | |
_logger.LogDebug($"Initial handler failed. Falling back to `{fallbackHandler.GetType().FullName}@HandleFallback`"); | |
return await fallbackHandler.HandleFallback(request, cancellationToken) | |
.ConfigureAwait(false); | |
}); | |
var response = await fallbackPolicy.ExecuteAsync(async () => await next()); | |
return response; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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