PMQ.Mediator
713 downloads · repositório
Mediator para .NET com pipeline de comportamento, integração de validação, streaming e publicação de notificação. 37 arquivos, 2.154 linhas.
O problema
Num serviço com muitos casos de uso, o controller vira despachante: injeta cinco dependências, valida, chama serviço, trata erro. O mediator tira isso do caminho: o controller entrega um comando e recebe um resultado, e tudo que acontece no meio é composição.
A decisão que amarra a suíte
Validação, log e transação não são responsabilidade do handler: são estágios que envolvem qualquer handler. O que torna esse pipeline diferente é o que ele faz quando a validação falha:
// Try to use the custom failure handler if registered
var failureHandler = serviceProvider.GetService<IValidationFailureHandler<TResponse>>();
if (failureHandler is not null)
return failureHandler.HandleFailure(failures);
// If no custom handler, throw a ValidationException
throw new ValidationException(failures);
Se existe um tratador registrado, a falha de validação vira valor de retorno; se não existe, cai para exceção. É o ponto onde o PMQ.Notifications se encaixa: quem adota a suíte inteira registra o tratador e a regra violada nunca vira exceção; quem usa só o mediator continua com o comportamento idiomático do .NET.
Foi assim que a fraqueza aceita no PMQ.Notifications, em que nada obriga o chamador a verificar, acabou resolvida estruturalmente. O pipeline verifica por todo mundo, antes de o handler existir.
Outras decisões
Validador resolvido por requisição, não no arranque. Se não há validador registrado para aquele comando, o pipeline segue direto. Custa uma consulta ao contêiner e evita obrigar todo comando a ter validador só para o pipeline não quebrar.
Validadores rodam em paralelo com Task.WhenAll, e os erros são concatenados. Serial devolveria
o primeiro conjunto de erros; paralelo devolve todos, que é a mesma razão de ser da suíte.
Streaming como abstração separada, com IStreamRequest e IStreamPipelineBehavior, porque
resposta única e sequência têm ciclo de vida diferente, e forçar as duas na mesma interface produz
um tipo que mente sobre metade dos casos.
Origem
Escrevi um mediator antes deste, para desacoplar módulos de um serviço corporativo, e ele funcionou. Este aqui é o que eu faria sabendo o que aquele me ensinou: mesma ideia, implementação melhor.