Sérgio Lacerda

Desenvolvedor Backend .NET e educador em tecnologia
Escrevo sobre desenvolvimento de software, carreira em TI e negócios

Desmistificando a Injeção de Dependência no .NET: por que ela existe e qual problema resolve

Por Sérgio Lacerda
Publicado em 15/03/2026

Neste artigo, você vai entender enfim o que é Injeção de Dependência, qual é o problema do acoplamento no desenvolvimento de software e como o mecanismo de DI do .NET ajuda a criar aplicações mais flexíveis, testáveis e fáceis de manter.

Animado por finalmente ter conseguido um estágio em desenvolvimento de sistemas, Pafúncio começa a participar de seu primeiro projeto de API em .NET, e não demora muito para que alguém veja seu código de iniciante e diga:

__ Não faça desse jeito, use injeção de dependência. Assim você evita acoplamento.

E logo aparece um exemplo de código pronto que é simplesmente copiado e colado sem saber muito bem o motivo.

Pafúncio fica meio sem jeito. Artigos e conversas rápidas com devs mais experientes (e sempre muito ocupados) parecem apenas repetir as mesmas fórmulas, mas sem explicar o motivo. E novamente o tal do “acoplamento”. O que afinal é isso?

Entendendo acoplamento e por que ele é ruim

O chamado “acoplamento” nada mais é do que o nível de dependência que existe entre partes do sistema. Para deixar isso mais claro, considere o exemplo abaixo, onde implementamos uma classe para controle de pedido que utiliza uma rotina de cálculo de descontos:


public class ServicoPedido
{
    private CalculadoraDescontoPadrao _calculadora = new CalculadoraDescontoPadrao();

    public decimal CriarPedido(decimal valor)
    {
        var desconto = _calculadora.Calcular(valor);

        return valor - desconto;
    }
}

Por sua vez, a classe calculadora poderia ser implementada assim:


public class CalculadoraDescontoPadrao
{
    public decimal Calcular(decimal valor)
    {
        return valor * 0.10m;
    }
}

Você deve ter percebido que a classe de serviço do pedido não tem como funcionar sem a classe CalculadoraDescontoPadrao, tanto que possui explicitamente um campo _calculadora que já começa criando uma instância dela.


private CalculadoraDescontoPadrao _calculadora = new CalculadoraDescontoPadrao();

Nesse exemplo, temos um alto acoplamento, ou seja, uma grande dependência entre as classes, e isso gera alguns problemas:

Ou seja, quanto mais o sistema cresce e se torna complexo, mais esse tipo de dependência passa a gerar problemas. Por esse motivo, é sempre preferível buscar baixo acoplamento entre os artefatos de software.

O que é Dependency Injection (Injeção de Dependência)

A Injeção de Dependência é um padrão que ajuda a reduzir o acoplamento entre classes. Sua ideia é bem simples e pode ser resumida em:

"Uma classe não deve criar suas próprias dependências.
Ela deve recebê-las de fora".

E para fazer isso, buscamos fazer com que as classes não dependam de implementações, mas sim de contratos, ou como se diz em orientação a objetos, de interfaces.

Dessa forma, criamos uma abstração para a calculadora de descontos em formato de interface:


public interface ICalculadoraDesconto
{
    decimal Calcular(decimal valor);
}

Em seguida, criamos a classe que implementa o contrato definido pela interface:


public class CalculadoraDescontoPadrao : ICalculadoraDesconto
{
    public decimal Calcular(decimal valor)
    {
        return valor * 0.10m;
    }
}

Por fim, modificamos o serviço para que a classe não tenha mais uma instância da calculadora. Ao invés disso, ela passa a receber a dependência pelo seu construtor:


public class ServicoPedido
{
    // O campo agora é do tipo interface e não mais de uma classe concreta
    private readonly ICalculadoraDesconto _calculadora;

    // A dependência da interface é passada como parâmetro do construtor da classe
    public ServicoPedido(ICalculadoraDesconto calculadora)
    {
        _calculadora = calculadora;
    }

    // Os métodos do serviço usam a calculadora normalmente como se fosse uma classe
    public decimal CriarPedido(decimal valor)
    {
        var desconto = _calculadora.Calcular(valor);

        return valor - desconto;
    }
}

Como o ASP.NET resolve isso automaticamente

O Pafúncio olha para isso com certa desconfiança. O conceito foge um pouco do convencional para um iniciante, mas até que é simples de entender. Mas uma coisa ainda o incomoda enquanto ele analisa o código anterior:

__ Se estou passando uma interface como dependência do construtor, como o .NET vai saber qual implementação (instância de classe) ele deve criar se isso não está explícito? – pergunta, ainda um pouco confuso, o nosso jovem desenvolvedor.

Para facilitar a nossa vida, o .NET possui um container de Injeção de Dependência embutido, e o ASP.NET Core já vem configurado para utilizá-lo automaticamente. Assim, só precisamos registrar essa dependência no arquivo Program.cs:


builder.Services.AddScoped<ICalculadoraDesconto, CalculadoraDescontoPadrao>();

Desse modo, sempre que um controller ou serviço precisar de ICalculadoraDesconto, o sistema fornecerá uma instância de CalculadoraDescontoPadrao, ou seja, o framework resolve isso automaticamente.

Scoped, Singleton ou Transient?

Quem tem um pouquinho mais de experiência com isso já deve ter se deparado com outras opções além do Scoped. Isso acontece porque ao registrar a dependência, também definimos o seu ciclo de vida (quando e quantas vezes uma instância será criada).

As três opções mais comuns são:

Transient: Uma nova instância é criada toda vez que alguém solicita o serviço (para objetos leves e que não guardam estado).


builder.Services.AddTransient<ICalculadoraDesconto, CalculadoraDescontoPadrao>();

Scoped: Uma instância é criada por requisição HTTP (ciclo de vida mais comum em APIs).


builder.Services.AddScoped<ICalculadoraDesconto, CalculadoraDescontoPadrao>();

Singleton: A aplicação cria uma única instância e todos usam a mesma (para configurações, serviços compartilhados etc.).


builder.Services.AddSingleton<ICalculadoraDesconto, CalculadoraDescontoPadrao>();

Benefícios de utilizar injeção de dependência

A injeção de dependência praticamente se tornou um dos pilares do desenvolvimento moderno de aplicações com .NET e sua utilização traz vários benefícios:

Conclusão

Enfim, o Pafúncio pode respirar aliviado e orgulhoso porque agora ele sabe os conceitos associados à injeção de dependência, seus benefícios e, principalmente, como implementar esse padrão para criar aplicações com qualidade e baixo acoplamento.

E você? Já tem segurança para usar Dependency Injection nos seus projetos?

Se curtiu esse artigo, me segue nas redes sociais para mais conteúdos como esse!

Voltar para textos