Descobri recentemente o atributo [FromServices], que faz parte do .Net Core desde a primeira versão.
O atributo [FromServices] permite injeção de dependência no nível do método em controladores Asp.Net Core.
Aqui está um exemplo:
public class UserController : Controller
{
private readonly IApplicationSettings _applicationSettings;
public UserController(IApplicationSettings applicationSettings)
{
_applicationSettings = applicationSettings;
}
public IActionResult Get([FromService]IUserRepository userRepository, int userId)
{
//Do magic
}
}
Por que usar injeção de método em vez de injeção de construtor? A explicação comum é quando um método precisa de dependências e não é usado em nenhum outro lugar, então é um candidato para usar o atributo [FromService].
Steven do StackOverflow postou uma resposta contra o uso do atributo [FromService]:
Para mim, o uso deste tipo de injeção de método em ações de controlador é uma má ideia, porque:
– O atributo
[FromServices]pode ser facilmente esquecido, e você só descobrirá quando a ação for invocada (em vez de descobrir na inicialização da aplicação, onde você pode verificar a configuração da aplicação)– A necessidade de se afastar da injeção de construtor por razões de desempenho é uma indicação clara de que os componentes injetados são muito pesados para criar, enquanto construtores de injeção devem ser simples, e a criação de componentes deve, portanto, ser muito leve.
– A necessidade de se afastar da injeção de construtor para evitar que construtores fiquem muito grandes é uma indicação de que suas classes têm muitas dependências e estão ficando muito complexas. Em outras palavras, ter muitas dependências é uma indicação de que a classe viola o Princípio da Responsabilidade Única. O fato de que suas ações de controlador podem ser facilmente divididas em diferentes classes é prova de que tal controlador não é muito coeso e, portanto, uma indicação de uma violação do SRP.
Então, em vez de esconder o problema raiz com o uso de injeção de método, recomendo o uso de injeção de construtor como único padrão de injeção aqui e tornar seus controladores menores. Isso pode significar, no entanto, que seu esquema de roteamento se torne diferente de sua estrutura de classe, mas isso é perfeitamente aceitável e totalmente suportado pelo ASP.NET Core.
De uma perspectiva de testabilidade, aliás, não deveria realmente importar se às vezes há uma dependência que não é necessária. Existem padrões de teste eficazes que resolvem este problema.
Concordo com Steven; se você precisar mover suas dependências do seu controlador para o método porque a classe está construindo muitas dependências, então é hora de dividir o controlador. Você quase certamente está violando o SRP.
O único caso de uso que vejo com injeção de método é late-binding quando uma dependência não está pronta na construção do controlador. Caso contrário, é melhor usar injeção de construtor.
Digo isso porque com injeção de construtor a classe sabe na construção se as dependências estão disponíveis. Com injeção de método, este não é o caso, não se sabe se as dependências estão disponíveis até que o método seja chamado.
Autor: Chuck Conway é um Engenheiro de IA com quase 30 anos de experiência em engenharia de software. Ele constrói sistemas de IA práticos—pipelines de conteúdo, agentes de infraestrutura e ferramentas que resolvem problemas reais—e compartilha o que está aprendendo ao longo do caminho. Conecte-se com ele nas redes sociais: X (@chuckconway) ou visite-o no YouTube e no SubStack.