Container de Injeção de Dependência para Go (Golang): Wire, Dig e Uber FX

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 Go (Golang): Wire, Dig e Uber FX



Injeção de Dependência (DI) é um padrão de projeto no qual um objeto recebe suas dependências externamente, em vez de criá-las por si só. Em Go (Golang), a DI é especialmente útil para criar código modular, testável e escalável. As ferramentas de DI mais populares para Go são Google Wire, Uber Dig e Uber FX. Neste artigo, examinaremos cada uma delas, suas características e exemplos de uso.



Por que a Injeção de Dependência é necessária em Go?

Go é uma linguagem estaticamente tipada com passagem explícita de parâmetros. Sem DI, os desenvolvedores frequentemente criam variáveis globais ou fábricas, o que dificulta os testes e a manutenção. Os containers de DI resolvem esses problemas:

  • Baixo acoplamento — os componentes dependem de interfaces, não de implementações concretas.
  • Testabilidade — é fácil substituir dependências por mocks.
  • Simplificação da configuração — o container resolve automaticamente o grafo de dependências.


Google Wire — geração de código em tempo de compilação

Wire da Google não é um container em tempo de execução, mas um gerador de código. Ele analisa funções construtoras e gera código para vincular dependências na fase de compilação. Isso resulta em zero sobrecarga durante a execução e detecção precoce de erros.



Instalação do Wire

go install github.com/google/wire/cmd/wire@latest


Exemplo de uso do Wire

Suponha que temos um serviço que depende de um banco de dados e um logger:

// main.gopackage main

import "fmt"

type Logger struct{}

func NewLogger() Logger { return Logger{} }

func (l Logger) Log(msg string) { fmt.Println(msg) }

type Database struct { logger Logger}

func NewDatabase(logger Logger) Database { return Database{logger: logger}}

type Service struct { db Database log Logger}

func NewService(db Database, log Logger) Service { return Service{db: db, log: log}}

Agora vamos criar o arquivo wire.go com a instrução para o Wire:

// wire.go//go:build wireinject// +build wireinject

package main

import "github.com/google/wire"

func InitializeService() Service { wire.Build(NewLogger, NewDatabase, NewService) return Service{}}

Vamos executar a geração:

wire

O Wire criará o arquivo wire_gen.go com o código de inicialização pronto:

// wire_gen.go// Code generated by Wire. DO NOT EDIT.

package main

func InitializeService() Service { logger := NewLogger() database := NewDatabase(logger) service := NewService(database, logger) return service}

Vantagens do Wire:

  • Erros em tempo de compilação.
  • Sem reflection, alta performance.
  • Código simples e previsível.

Desvantagens do Wire:

  • Requer uma etapa separada de geração.
  • Difícil de usar com dependências dinâmicas.


Uber Dig — container em tempo de execução com reflection

Dig da Uber é um container que opera em tempo de execução. Ele usa reflection para analisar tipos e resolver automaticamente as dependências. O Dig fornece uma API simples para registrar construtores e extrair objetos.



Instalação do Dig

go get go.uber.org/dig


Exemplo de uso do Dig

package main

import ( "fmt" "go.uber.org/dig")

type Config struct { Port int}

func NewConfig() *Config { return &Config{Port: 8080}}

type Server struct { config *Config}

func NewServer(c *Config) *Server { return &Server{config: c}}

func (s *Server) Start() { fmt.Print

Recommendations