Container de Injeção de Dependência Swift: Swinject para iOS/macOS

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Container de Injeção de Dependência para Swift (iOS/macOS): Swinject

No desenvolvimento moderno de iOS e macOS com Swift, os padrões arquiteturais desempenham um papel fundamental na criação de código sustentável e testável. Uma das ferramentas mais poderosas para implementar o Princípio da Inversão de Dependência (Dependency Inversion Principle) é o Swinject — um container DI leve, porém funcional, escrito em Swift. O Swinject permite gerenciar centralizadamente a criação de objetos e suas dependências, liberando o desenvolvedor da construção manual do grafo de objetos.



O que é Injeção de Dependência e para que serve um container?

Injeção de Dependência (DI) é uma técnica na qual um objeto recebe suas dependências externamente, em vez de criá-las por conta própria. Isso reduz o acoplamento do código e simplifica os testes unitários. No entanto, em projetos grandes, a injeção manual de dependências resulta em código extenso. É aqui que o container DI entra em ação, pois:

  • Automatiza a criação e a ligação de objetos
  • Gerencia o tempo de vida dos objetos (singletons, novas instâncias)
  • Facilita a substituição de implementações (por exemplo, para testes)
  • Aumenta a legibilidade e a sustentabilidade do código


Instalação do Swinject

O Swinject pode ser instalado via Swift Package Manager, CocoaPods ou Carthage. Para SPM, adicione em Package.swift:

dependencies: [    .package(url: "https://github.com/Swinject/Swinject.git", from: "2.8.0")]

Ou via CocoaPods:

pod 'Swinject', '~> 2.8'


Conceitos principais do Swinject

A biblioteca baseia-se em vários componentes-chave:

  • Container — o registrador e resolvedor principal de dependências
  • Service — o tipo que é registrado (geralmente um protocolo ou classe)
  • Component — a implementação concreta do serviço
  • Scope — define o tempo de vida do objeto (transient, graph, container, weak)


Exemplo prático: registro e resolução de dependências

Vamos considerar um cenário típico — um aplicativo com um serviço de autenticação e um controlador que o utiliza.

// Protocolo do serviçoprotocol AuthServiceProtocol {    func login(username: String, password: String) -> Bool}

// Implementaçãoclass AuthService: AuthServiceProtocol { func login(username: String, password: String) -> Bool { // Lógica de autenticação return username == "admin" && password == "1234" }}

// Controlador dependente de AuthServiceProtocolclass LoginViewController { private let authService: AuthServiceProtocol // Injeção via inicializador init(authService: AuthServiceProtocol) { self.authService = authService } func authenticate(user: String, pass: String) { if authService.login(username: user, password: pass) { print("Login bem-sucedido") } else { print("Dados inválidos") } }}

// Configuração do containerlet container = Container()container.register(AuthServiceProtocol.self) { _ in AuthService() }container.register(LoginViewController.self) { r in LoginViewController(authService: r.resolve(AuthServiceProtocol.self)!)}

// Usolet controller = container.resolve(LoginViewController.self)!controller.authenticate(user: "admin", pass: "1234") // Login bem-sucedido


Gerenciamento do tempo de vida (Scopes)

O Swinject suporta quatro scopes integrados:

  • .transient — uma nova instância é criada a cada vez (padrão)
  • .graph — uma instância por grafo de resolução (usado por padrão na maioria dos casos)
  • .container — singleton dentro do container
  • .weak — referência fraca, obj

Recommendations