Conteneur d'injection de dépendances pour Go (Golang) : Wire, Dig et Uber FX

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Conteneur d'injection de dépendances pour Go (Golang) : Wire, Dig et Uber FX

\n\n

L'injection de dépendances (DI) est un modèle de conception dans lequel un objet reçoit ses dépendances de l'extérieur, plutôt que de les créer lui-même. En Go (Golang), la DI est particulièrement utile pour créer un code modulaire, testable et évolutif. Les outils de DI les plus populaires pour Go sont Google Wire, Uber Dig et Uber FX. Dans cet article, nous examinerons chacun d'eux, leurs caractéristiques et des exemples d'utilisation.

\n\n

Pourquoi l'injection de dépendances en Go ?

\n

Go est un langage typé statiquement avec un passage explicite de paramètres. Sans DI, les développeurs créent souvent des variables globales ou des fabriques, ce qui complique les tests et la maintenance. Les conteneurs DI résolvent ces problèmes :

\n
    \n
  • Faible couplage — les composants dépendent d'interfaces, et non d'implémentations concrètes.
  • \n
  • Testabilité — il est facile de remplacer les dépendances par des mocks.
  • \n
  • Simplification de la configuration — le conteneur résout automatiquement le graphe des dépendances.
  • \n
\n\n

Google Wire — génération de code à la compilation

\n

Wire de Google n'est pas un conteneur d'exécution, mais un générateur de code. Il analyse les fonctions constructeurs et génère le code pour lier les dépendances à l'étape de compilation. Cela offre une charge nulle pendant l'exécution et une détection précoce des erreurs.

\n\n

Installation de Wire

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

Exemple d'utilisation de Wire

\n

Supposons que nous ayons un service qui dépend d'une base de données et d'un journaliseur :

\n
// main.go\npackage main\n\nimport "fmt"\n\ntype Logger struct{}\n\nfunc NewLogger() Logger { return Logger{} }\n\nfunc (l Logger) Log(msg string) { fmt.Println(msg) }\n\ntype Database struct {\n    logger Logger\n}\n\nfunc NewDatabase(logger Logger) Database {\n    return Database{logger: logger}\n}\n\ntype Service struct {\n    db  Database\n    log Logger\n}\n\nfunc NewService(db Database, log Logger) Service {\n    return Service{db: db, log: log}\n}
\n

Créons maintenant un fichier wire.go avec les instructions pour Wire :

\n
// wire.go\n//go:build wireinject\n// +build wireinject\n\npackage main\n\nimport "github.com/google/wire"\n\nfunc InitializeService() Service {\n    wire.Build(NewLogger, NewDatabase, NewService)\n    return Service{}\n}
\n

Lançons la génération :

\n
wire
\n

Wire créera un fichier wire_gen.go avec le code d'initialisation prêt :

\n
// wire_gen.go\n// Code generated by Wire. DO NOT EDIT.\n\npackage main\n\nfunc InitializeService() Service {\n    logger := NewLogger()\n    database := NewDatabase(logger)\n    service := NewService(database, logger)\n    return service\n}
\n

Avantages de Wire :

\n
    \n
  • Erreurs à l'étape de compilation.
  • \n
  • Pas de reflection, haute performance.
  • \n
  • Code simple et prévisible.
  • \n
\n

Inconvénients de Wire :

\n
    \n
  • Nécessite une étape de génération séparée.
  • \n
  • Difficile à utiliser avec des dépendances dynamiques.
  • \n
\n\n

Uber Dig — conteneur d'exécution avec reflection

\n

Dig d'Uber est un conteneur fonctionnant pendant l'exécution. Il utilise la reflection pour analyser les types et résoudre automatiquement les dépendances. Dig fournit une API simple pour enregistrer des constructeurs et extraire des objets.

\n\n

Installation de Dig

\n
go get go.uber.org/dig
\n\n

Exemple d'utilisation de Dig

\n
package main\n\nimport (\n    "fmt"\n    "go.uber.org/dig"\n)\n\ntype Config struct {\n    Port int\n}\n\nfunc NewConfig() *Config {\n    return &Config{Port: 8080}\n}\n\ntype Server struct {\n    config *Config\n}\n\nfunc NewServer(c *Config) *Server {\n    return &Server{config: c}\n}\n\nfunc (s *Server) Start() {\n    fmt.Print                    

Recommendations