DEV Community

Cover image for Crítica - MediatR: Pra Quê?
William Santos
William Santos

Posted on

Crítica - MediatR: Pra Quê?

Olá!

Este é um post da seção Crítica, e nele pretendo explorar o uso da biblioteca MediatR em aplicações reais e provocar uma reflexão a respeito.

Vamos lá!

O que é o MediatR?

Antes de adentrarmos a provocação proposta, vamos entender sobre o que estamos falando.

O MediatR se propõe a ser uma implementação do padrão Mediator (em inglês) que, basicamente, é um meio de propagar mensagens sem que seu produtor precise conhecer seus consumidores.

Além disso, a biblioteca possui uma implementação que sugere a mesma como um roteador de comandos e consultas, o que faz com que muitos imaginem, erroneamente, ser uma implementação de CQRS, o que explico neste post.

E é aqui que começamos a entender o problema.

O Problema

Quando o MediatR é utilizado para propagar comandos, a intenção é impedir que um Controller, por exemplo, tenha um "Constructor Dependency Explosion", ou seja, que tenha uma série de dependências injetadas via construtor e passe a depender, apenas, de uma instancia de IMediator.

Isso traz algumas questões:

  1. O problema original é a necessidade de utilizar várias dependências para a execução de um único comando ou consulta, e não é o uso do MediatR que vai resolver, ele vai apenas mascarar pois seus handlers tendem a continuar com a explosão de dependências em seus construtores, ainda que em número menor ao do Controller.
  2. Ao utlizar o MediatR adiciona-se uma camada de indireção por meio de sua interface IMediator, o que obriga o programador a buscar a implementação do handler correspondente àquela operação para entender o que se passa.
  3. Normalmente o uso do MediatR esconde uma falha de design imensa que é a criação de uma quantidade enorme de handlers com uma quantidade enorme de código, disfarçando o que o Controller escancararia: código excessivo.
  4. Toda vez que um Controller que utiliza IMediator é construído, também é uma instância do Mediator, uma vez que sua configuração padrão o cria como uma instância transiente.
  5. Um componente fundamental de sua aplicação, seu roteador de operações, passa a ser uma dependência externa, o que te torna vulnerável a eventuais falhas, as famosas breaking changes ou até mesmo, como é possível ver aqui, uma mudança de licenciamento. Ou seja, não é mais um simples apoio, passa a ser um custo difícil de reverter.

Ou seja, em parte significativa dos casos, a maioria na minha experiência, o MediatR apenas mascara uma deficiência do design da aplicação, tornando-a mais complexa e mais difícil de ler.

Que Vantagem Maria Leva?

Diante das questões apresentados acima, proponho a seguinte pergunta: qual o ganho real que o uso do MediatR te traz?

É esconder a bagunça? Então ele só piora.
É separar responsabilidades? Então você não precisa dele.
É isolar dependências? Então você não precisa dele.

Entendo que faça sentido buscar responder a essa pergunta, indo além das questões aqui colocadas. Ou seja, considerando qualquer outro uso que você entenda fazer sentido para a biblioteca.

Aliás, te incentivo a trazer nos comentários do post, ou nas minhas redes, quais ganhos você percebe no uso da biblioteca que compense seus custos. Seria excelente ter pontos de vista diversos pra que eu mesmo considere, ou reconsidere.

MediatR é de Fácil Replicação

Por último, depois de responder a pergunta cima, ofereço uma alternativa super simples: construir um mediador você mesmo. No fim do dia, tudo de que você precisa é de uma interface que te permita percorrer uma lista de handlers e escolher o adequado para executar sua operação.

Nesta série de posts, meu colega e referência na comunidade .NET, Angelo Belchior, demonstra como é simples. Ele não pretende criar uma réplica utilizável em produção, apenas te guiar para uma implementação própria.

Conclusão

Evito ao máximo o uso do MediatR como um roteador de comandos e consultas, prefiro injetar meus handlers diretamente no Controller correspondente à operação que pretendo realizar.
Acho a biblioteca ruim? Nem de longe, tenho até um tutorial sobre ela aqui no Blog.
Mas entendo não haver ganhos significativos diante das questões apresentadas a menos que a aplicação se beneficie (como se beneficia a do exemplo do tutorial) e, por isso, ofereço uma solução alternativa no post sobre mal-entendidos em CQRS já referenciado (mas que você pode acessar por aqui também).

Gostou deste formato de post? Deixe-me saber pelos indicadores. Tem alguma dúvida ou comentário? Por favor, descreva abaixo.

Muito obrigado por ler até aqui e até o próximo post!

Top comments (2)

Collapse
 
hsouzaeduardo profile image
Henrique souza

Excelente reflexão, William!

Já tive experiências em frameworks corporativos que estavam totalmente acoplados a libs como o MediatR, e sempre me soou como um risco técnico e comercialmente sensível. A leitura do seu artigo me ajudou a esclarecer um opinião pessoal. Especialmente ao destacar pontos como a criação de instâncias transientes a cada request, algo que muitos não percebem no início, mas que pode ter impacto direto em 3 aspectos que levo muito em consideração: custo, **performance **e **escalabilidade **da aplicação.

Gosto da ideia de manter os controllers limpos e evitar acúmulo de lógica de negócio, mas a um certo ponto esse no "higienismo arquitetural" começa a esconder a complexidade real do sistema, o que dificulta a leitura, a rastreabilidade e até a observabilidade dos fluxos que realmente importam.

No fim, é como você bem colocou: às vezes o MediatR resolve um problema que nem tínhamos. Concordo que, em muitos casos, injeção direta e clareza no código são mais sustentáveis a longo prazo.

Parabéns pela abordagem crítica, direta e prática a comunidade ganha muito com esse tipo de artigo !

Collapse
 
wsantosdev profile image
William Santos

Muito obrigado, Henrique. É essa mesma a ideia.

E quase não te reconheço com esse avatar. Haha!