golang : bibliothèque d'injection de dépendances - Wire

Qu'est-ce que l'injection de dépendance

L'injection de dépendance (DI en abrégé) est un modèle de conception de logiciel et l'une des techniques de mise en œuvre de l'inversion de contrôle. Ce modèle permet à un objet de recevoir d'autres objets dont il dépend. Les "dépendances" font référence aux objets requis par le récepteur. « Injection » fait référence au processus de transmission des « dépendances » au récepteur. Après "injection", le récepteur appellera la "dépendance". Ce modèle garantit que tout objet souhaitant utiliser un service donné n'a pas besoin de savoir comment configurer ces services. Au lieu de cela, le code externe (l'injecteur) qui se connecte à l'objet récepteur (tel que le client) ne sait pas qu'il existe pour fournir les services requis par la partie réceptrice.

L'injection de dépendance implique quatre concepts :

  • Service : Toute classe qui fournit des fonctionnalités utiles.
  • Client : La classe qui consomme le service.
  • Interface : les clients ne doivent pas connaître les détails de la mise en œuvre du service, ils doivent uniquement connaître le nom et l'API du service
  • Injecteur : Injecteur, également appelé assembleur, conteneur, fournisseur ou usine. Responsable de la présentation des services aux clients.

L'injection de dépendances sépare la construction d'objet de l'injection d'objet. Par conséquent, le nouveau mot-clé de création d'objets peut également disparaître.

Il existe deux types de frameworks d'injection de dépendances pour Golang :

  • Injection de dépendances au moment de l'exécution par réflexion, un représentant typique est la fouille open source d'Uber ;
  • Générer du code via générer, un représentant typique est le fil open source de Google.

L'utilisation de dig sera plus puissante, mais l'inconvénient est que les erreurs ne peuvent être trouvées qu'au moment de l'exécution, ce qui peut entraîner des bogues cachés si vous ne faites pas attention. L'inconvénient de l'utilisation de wire est qu'il y a plus de restrictions fonctionnelles, mais l'avantage est que des problèmes peuvent être trouvés lors de la compilation, et le code généré n'est en fait pas très différent de notre propre code manuscrit, qui est plus intuitif et moins lourd mentalement, donc le fil est plus recommandé.

qu'est-ce que le fil

Wire est un outil de génération de code de dépendance d'injection pour le langage go qui est open source par google. Il peut générer le code go d'injection de dépendance correspondant en fonction de votre code.

Contrairement à d'autres outils d'injection de dépendances, tels que Uber's Dig et Facebook's Inject, ces deux outils implémentent l'injection de dépendances à l'aide de la réflexion et sont une injection de dépendances d'exécution.

Wire est une injection de dépendance qui génère du code lors de la compilation du code, et est une injection de dépendance au moment de la compilation qui injecte du code de dépendance lors de la compilation. De plus, lors de la génération de code, s'il y a un problème avec l'injection de dépendance, une erreur se produira lors de la génération du code dépendant, et le problème peut être signalé au lieu d'avoir à attendre que le code s'exécute pour exposer le problème.

Fournisseurs et Injecteurs

Tout d'abord, vous devez comprendre deux concepts de base du fil : fournisseur et injecteur

Les étapes de l'injection de dépendances sont les suivantes :

  • Premièrement: besoin de créer une instance de new
  • Deuxièmement: "injectez" la nouvelle instance de classe dans la classe qui doit l'utiliser via le constructeur ou d'autres méthodes
  • Troisième : utilisez cette nouvelle instance dans la classe.

À partir des étapes ci-dessus pour comprendre les deux concepts de base du fil : fournisseur et injecteur

  • Le fournisseur est équivalent à la nouvelle instance de classe ci-dessus
  • Inject revient à agréger les fonctions dépendantes requises avant l'action "injection" et à générer des dépendances basées sur les fonctions agrégées.

Fournisseur : Fournir un
injecteur d'objets : Responsable de la génération de nouveaux programmes basés sur les dépendances d'objets.

fournisseur:

Provider est une fonction go ordinaire, qui peut être comprise comme un constructeur d'objet. Fournit des "artefacts" pour générer la fonction Injector ci-dessous.

La fonction NewUserStore() suivante peut être considérée comme un fournisseur. Cette fonction doit passer les paramètres *Config et *mysql.DB 2.

// NewUserStore 是一个 provider for *UserStore,*UserStore 依赖 *Config,*mysql.DB
func NewUserStore(cfg *Config, db *mysql.DB) (*UserStore, error) {
    
    ... ...}

// NewDefaultConfig 是一个 provider for *Config,没有任何依赖
func NewDefaultConfig() *Config {
    
    ...}

// NewDB 是 *mysql.DB 的一个 provider ,依赖于数据库连接信息 *ConnectionInfo
func NewDB(info *ConnectionInfo) (*mysql.DB, error){
    
    ...}

Les fournisseurs peuvent être combinés en un ensemble d'ensembles de fournisseurs. Ceci est utile pour les fournisseurs qui sont souvent utilisés ensemble. Ils peuvent être combinés à l'aide de la méthode wire.NewSet

var SuperSet = wire.NewSet(NewUserStore, NewDefaultConfig)

Vous pouvez également ajouter d'autres ensembles de fournisseurs à un ensemble de fournisseurs

import (
    “example.com/some/other/pkg”
)

// ... ...
var MegaSet = wire.NewSet(SuperSet, pkg.OtherSet)

Fonction wire.NewSet() :
cette fonction peut combiner des fournisseurs associés et les utiliser. Bien sûr, il peut également être utilisé seul, comme var Provider = wire.NewSet(NewDB).
La valeur de retour de cette fonction NewSet peut également être utilisée comme paramètre d'autres fonctions NewSet, telles que le SuperSet ci-dessus utilisé comme paramètre.

Injecteur

Nous écrivons un programme pour combiner ces fournisseurs (comme la fonction initUserStore() dans l'exemple suivant), et la commande wire dans wire appellera les fournisseurs dans l'ordre des dépendances pour générer une fonction plus complète, qui est l'injecteur.

Commencez par écrire la fonction de signature qui génère l'injecteur, puis utilisez la commande wire pour générer la fonction correspondante.

Les exemples sont les suivants :

// +build wireinject

func initUserStore(info *ConnectionInfo) (*UserStore, error) {
    
    
    wire.Build(SuperSet, NewDB) // 声明获取 UserStore 需要调用哪些 provider 函数
    return nil, nil
}

Utilisez ensuite la commande wire pour générer la fonction d'injecteur à partir de la fonction initUserStore ci-dessus, et la fonction générée correspond au nom de fichier wire_gen.go.

wire 命令:
You can generate the injector by invoking Wire in the package directory。
直接在生成 injector 函数的包下,使用 wire 命令,就可以生成 injector 代码。

wire.Build() 函数:

它的参数可以是 wire.NewSet() 组织的一个或多个 provider,也可以直接使用 provider。

Joignez-vous à Kratos

Utilisez la commande suivante pour installer l'outil de ligne de commande de Wire dans le chemin global pour la génération de code.

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

code de scène

Ici, on fait un "service utilisateur".

Selon la mise en page officielle recommandée par Kratos, nous divisons le service dans les couches suivantes : serveur, service, biz, données.

Je suppose que tu aimes

Origine blog.csdn.net/zhizhengguan/article/details/130138048
conseillé
Classement