Ao criar apps iOS com Swift, você inevitavelmente se depara com esta dúvida.
“Afinal, qual abordagem de injeção de dependência devo usar?”
Vou começar pela conclusão.
A menos que exista um motivo específico, a injeção pelo construtor (init) é o mais próximo da escolha certa.
Vou explicar o motivo e quando usar as outras duas abordagens, com base em experiência prática.
Três abordagens de injeção: o essencial primeiro
Antes de confundir as coisas, vamos estabelecer a base. No Swift, há três formas principais de fornecer dependências.
- Injeção pelo construtor (init) —
initrecebe dependências como parâmetros - Injeção por propriedade —
varatribui depois à propriedade - Injeção por método — injeta por meio de um método separado
Este é o código da abordagem mais recomendada: injeção pelo construtor.
final class OrderService {
private let repo: MemberRepository // let garante a imutabilidade
init(repo: MemberRepository) { // construtor(init) injeção
self.repo = repo
}
}
Como usa apenas a sintaxe nativa do Swift, sem bibliotecas extras, o código fica limpo.
Já a injeção por propriedade é curta assim.
final class OrderService {
var repo: MemberRepository! // parece conveniente por ter uma linha só…
}
À primeira vista, a injeção por propriedade parece claramente mais simples. Mas essa conveniência pode trazer problemas depois.
Por que a injeção por propriedade é desaconselhada?
Vou começar por algo que vivenciei.
A injeção por propriedade é realmente incômoda nos testes. Se você esquecer de injetar depois de criar o objeto, ocorre um crash por forced unwrap, e o tipo, sozinho, não mostra o que precisa ser fornecido para completá-lo.
Com a injeção pelo construtor, você pode inserir diretamente um mock, como OrderService(repo: mockRepo), usando código Swift puro.
O segundo problema é não poder usar a palavra-chave let.
A injeção pelo construtor permite declarar as propriedades como let, tornando-as imutáveis depois da injeção.
Já a injeção por propriedade usa var, então o valor pode ser alterado a qualquer momento, abrindo espaço para erros.
O terceiro problema são as referências cíclicas.
Se A referencia B e B referencia A, a injeção por propriedade pode não revelar isso até o app ser executado. O problema só aparece ao entrar naquela tela.
A injeção pelo construtor revela o problema no momento da criação do objeto (e, se o design estiver confuso, ele pode nem compilar), permitindo corrigi-lo muito mais cedo.
Tabela comparativa de relance
Explicar em palavras pode confundir, então organizei tudo em uma tabela. (Diretriz da comunidade Swift em 2026)
| Categoria | Injeção pelo construtor (init) | Injeção por propriedade | Injeção por método |
|---|---|---|---|
| Imutabilidade (let) | Possível ⭕ | Impossível ❌ | Impossível ❌ |
| Facilidade para testes | Alta | Baixa | Média |
| Detecção de referências cíclicas | Imediata na criação | Detectada tarde | Detectada tarde |
| Dependência obrigatória/opcional | Adequada para obrigatórias | Distinção ambígua | Adequada para opcionais |
| Concisão do código | Média | Muito concisa | Média |
A tendência fica clara só de olhar a tabela, não é?
A injeção pelo construtor se destaca na maioria dos critérios. Por isso, a documentação de bibliotecas de DI como Swinject e Factory também a recomenda como padrão.
Então, quando usar as outras duas abordagens?
Isso não significa que você deva usar sempre a injeção pelo construtor. Cada abordagem tem seu lugar.
A injeção por método combina bem com dependências opcionais.
Quando o alvo da injeção não é obrigatório — algo usado se estiver disponível, mas dispensável — você pode adicioná-lo com flexibilidade por um método como configure(with:).
A injeção por propriedade ainda pode fazer sentido quando não controlamos diretamente a inicialização, como em um view controller criado por storyboard.
No código comum da aplicação, é melhor evitá-la sempre que possível.
Em resumo:
- Dependência obrigatória → injeção pelo construtor
- Dependência opcional → injeção por método
- Injeção por propriedade no código comum → evitar
Perguntas frequentes
P. Bibliotecas de DI como a Factory tornam a injeção pelo construtor mais fácil?
Sim. Ao registrar no Swinject ou na Factory como criar dependências, o container cria os objetos passados ao construtor. O código fica menor, preservando vantagens como a let imutabilidade.
P. E se o construtor ficar com parâmetros demais?
Isso não é um problema da abordagem de injeção, mas um sinal de que a classe está fazendo coisas demais. Primeiro, considere dividir as responsabilidades entre classes.
P. Uma biblioteca de DI é necessária até em projetos pequenos?
Não. Em um projeto com poucas telas, a injeção pelo construtor usando Swift puro, passando as dependências diretamente init, já é suficiente.
É fácil se sentir atraído pela praticidade da injeção por propriedade no início, mas, ao escrever testes e colaborar, você percebe na prática por que as vantagens da injeção pelo construtor são tão enfatizadas.
Se estiver em dúvida, comece pela injeção pelo construtor. Você agradecerá essa escolha à medida que o código crescer.

