Injection de dépendance avec samber/do

a marqué ce sujet comme résolu.

Bonjour, Je suis en train d’essayer d’utiliser le package samber/do en le combinant avec les fonctions init() de Go.

Mon but est déviter d’avoir un fichier d'initalisation qui va configurer mes services et mon application. Je souhaite éviter un tel fichier car il est souvent très volumineux et peu pratique à modifier.

On peut avoir un exemple de ça ici

func main() {
	// Usual way to initialize out app
	userFetch := usualinfra.NewUserFetch("example.com", "key")
	locFetch := usualinfra.NewLocationFetch("location.com", "key")

	usualApp := usualdomain.NewApp(userFetch, locFetch)

	// Do stuff with our app
	usualApp.DoStuff()
[...]

Ici j’initialise les services userFetch et locFetch que je donne en suite à mon application. Dans le cas où j’ai beaucoup de service avec beaucoups de configuration le fichier peut-être très long, c’est ce que je cherche à éviter.


Pour éviter cette suite d’initialisation de service je suis donc parti en faisant quelque chose comme ça:

func init() {
	uf := do.MustInvoke[*userfetcher.UserFetch](nil)
	lf := do.MustInvoke[*locationfetcher.LocationFetch](nil)

	do.Provide(
		nil,
		func(i *do.Injector) (*App, error) {
			return NewApp(uf, lf), nil
		},
	)
}

Dans la fonction init du package de mon application, j’utilise samber pour récupérer les instances des service de localisation et des utilisateurs. En suite je crée mon application.

Les services de localisation et des utilisateurs sont eux crée de la même manière, dans la fonction init de leurs package.

func init() {
	do.Provide(
		nil,
		func(i *do.Injector) (*LocationFetch, error) {
			return NewLocationFetch("location.com", "key"), nil
		},
	)
}

Ici on remarque que je crée mon service de localisation et je l’enregistre dans samber.

Avec cette méthode pour initialiser mes service, je me retrouve donc avec seulement ceci dans la fonction main:

func main() {
[...]

        // Initialize the app with samber/do
	samberApp := do.MustInvoke[*samber.App](nil)

	// Do stuff with our app
	samberApp.DoStuff()
}

Quels sont vos avis sur la méthode d’utiliser les fonction init de Go combiné à samber pour initialiser plus facilement ses service ? Est ce que vous avec des expériences avec une tel méthode ?

Voici le dépot github dans lequel sont mes exemples.

+0 -0

Salut,

J’ai du mal à comprendre en quoi c’est avantageux de répartir le code de création de chaque service plutôt qu’avoir un main() qui est lisible linéairement.

Tu parles d’éviter un fichier très long, on parle de quelle taille ? Est-ce gênant ? Instinctivement, je n’aurai pas envie de (1) ajouter une dépendance et (2) éparpiller une procédure linéaire simple (initialisation des services) en pleins de petits blocs dans chaque fichier.

Le principal problème que je vois, outre la complexité ajoutée, est qu’il devient difficile de savoir quels services sont utilisées en pratique. Il faut lire chaque fichier pour voir le comportement.

Pour moi l’avantage de répartir l’initialisation de chaque service indépendament est d’éviter d’avoir tout au même endroit. J’ai tendance à considérer un service comme un package qui est indépendant et donc cela me permet d’abstraire leurs initialisation. C’est son propre package qui se débrouille pour savoir comment il doit-être initialiser.
Le but est aussi d’éviter tout le code qui ne me semble pas intéressant qui est uniquement de récupérer des valeurs dans des variables d’environement, des arguments, … et de les donner aux fonctions d’initialisations des service.

Quand je parle d’un fichier très long c’est plusieurs miliers de lignes qui vont juste initialiser des services avec les valeurs qui vont être récupérer depuis l’environement ou autre.


Le package envconfig semble intéressant, cependant je pense qu’il ne résoudrait qu’une partie de ce que je cherche à faire. Plutot que de récupérer les variables d’environement, par exemple avec viper, il me permetterait d’avoir mes service (qui sont des struct) directement initialisé de ce que je vois.
Il me resterait parcontre a avoir dans mon main plus que l’appel à la fonction envconfig.Process pour chaque service. Je pense neanmoins que ce package pourrait me permettre de raccourcir le code pour récupérer ces valeurs.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte