Conceito e Inversão de Controle
ResumoInjeção de dependência (DI) é entregar a uma classe as coisas de que ela precisa, em vez de ela mesma criá-las. Isso inverte o controle (IoC), reduz acoplamento e torna o código testável.
1. Objetivos de Aprendizagem#
- Entender dependência, acoplamento e IoC.
- Aplicar injeção por construtor.
- Perceber o ganho em testabilidade.
2. Pré-requisitos#
- Interfaces (tópico 5.3).
3. Conceito#
Quando uma classe faz new OutraClasse() internamente, ela fica acoplada àquela implementação: não dá para trocar nem testar isoladamente. A inversão de controle transfere a responsabilidade de criar dependências para fora da classe. A forma mais comum é a injeção por construtor: a classe declara o que precisa (idealmente uma interface) e recebe pronto.
O porquê: baixo acoplamento (troco a implementação sem tocar no consumidor), testabilidade (injeto um mock) e clareza (as dependências ficam explícitas no construtor).
4. Mão na Massa#
4.1. Setup#
dotnet new console -n Catalog.Di
cd Catalog.Di
4.2. Implementação Passo a Passo#
- Acoplado (evite):
public class ServicoProdutoRuim
{
private readonly RepositorioSql _repo = new(); // acoplado ao concreto
}
public class RepositorioSql { }
- Com injeção por construtor (prefira):
public interface IRepositorioProduto
{
string ObterNome(Guid id);
}
public class ServicoProduto
{
private readonly IRepositorioProduto _repo;
public ServicoProduto(IRepositorioProduto repo) => _repo = repo; // injetado
public string Descrever(Guid id) => $"Produto: {_repo.ObterNome(id)}";
}
- Composição (quem monta as peças):
IRepositorioProduto repo = new RepositorioFake();
var servico = new ServicoProduto(repo); // injeta a dependência
public class RepositorioFake : IRepositorioProduto
{
public string ObterNome(Guid id) => "Mouse (fake)";
}
4.3. Executando#
dotnet run
5. Exemplo Completo#
ServicoProduto depende de IRepositorioProduto. Em produção você injeta a versão real; em teste, RepositorioFake — sem alterar uma linha do serviço.
6. Boas Práticas e Armadilhas#
| Faça | Evite |
|---|---|
| Injeção por construtor de interfaces | new de dependências concretas dentro da classe |
| Dependências explícitas e obrigatórias no construtor | Service locator escondendo dependências |
| Classes com poucas dependências | Construtores com 10 parâmetros (sinal de excesso de responsabilidade) |
Notainjeção por construtor é o padrão recomendado. Injeção por propriedade/método existe, mas é exceção — o construtor deixa claras as dependências obrigatórias.
7. Segurança e Produção#
- DI facilita substituir implementações (ex.: trocar um provedor externo) e isolar testes de recursos reais — base de código sustentável.
8. Exercícios#
- Fácil: refatore uma classe que faz
newpara receber a dependência no construtor. - Médio: crie duas implementações de uma interface e injete cada uma.
- Desafio: escreva um teste que injeta um fake e verifica o comportamento do serviço.
9. Resumo#
DI entrega dependências prontas (via construtor), invertendo o controle. Depender de interfaces reduz acoplamento e habilita testes. Evite new de concretos dentro das classes.
10. Próximos Passos#
A seguir, o container de DI da Microsoft que automatiza essa composição.
11. Referências#
- Microsoft Learn — Injeção de dependência no .NET
- Microsoft Learn — Injeção de dependência no ASP.NET Core
- Microsoft Learn — Princípios SOLID: inversão de dependência