Skip to content

Posts

Quando Usar o Atributo FromService

20 de novembro de 2019 • 3 min de leitura

Quando Usar o Atributo FromService

Recentemente descobri o atributo [FromServices], que faz parte do .Net Core desde a primeira versão.

O atributo [FromServices] permite injeção de dependência a nível de 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:

– Tal 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 performance é 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 os construtores se tornem muito grandes é uma indicação de que suas classes têm muitas dependências e estão se tornando 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 violação do SRP.

Então, em vez de esconder o problema raiz com o uso de injeção de método, aconselho o uso de injeção de construtor como único padrão de injeção aqui e torne seus controladores menores. Isso pode significar, no entanto, que seu esquema de roteamento se torna diferente da estrutura de sua classe, mas isso é perfeitamente aceitável e completamente 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ê precisa 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 é especialista em engenharia de software e IA Generativa. Conecte-se com ele nas redes sociais: X (@chuckconway) ou visite-o no YouTube.

↑ Voltar ao topo

Você também pode gostar