Injection de dépendance et Singleton. S'agit-il de deux concepts entièrement différents?

17

J'ai entendu parler de l'utilisation de l'injection de dépendance sur Singleton pour mon collègue. Je ne sais toujours pas si ce sont deux motifs orthogonaux qui peuvent être remplacés l'un par l'autre? Ou DI est-il une méthode pour rendre le modèle Singleton testable?

Veuillez consulter l'extrait de code suivant.

    IMathFace obj = Singleton.Instance;

    SingletonConsumer singConsumer = new SingletonConsumer(obj);

    singConsumer.ConsumerAdd(10,20);

Le SingletonConsumeraccepte un paramètre de type IMathFace. Au lieu d'accéder à la classe singleton en interne, SingletonConsumerobtient l'instance singleton transmise par l'appelant. Est-ce un bon exemple de consommation de classe singleton via l'injection de dépendances?

logeeks
la source
Pouvez-vous me dire comment DI peut remplacer le singleton?
7
Singleton est un modèle de conception. DI / IoC est une technique.
Dave
2
DI ne peut pas remplacer Singleton pas plus qu'une banane ne pourrait remplacer un carburateur. Ce sont des concepts complètement différents.
Dave
donc mon exemple est valide.
1
Oui, mais cela peut se faire au détriment de l'encapsulation (ce qui est également vrai pour les non-singleton) voir: stackoverflow.com/questions/1005473/…

Réponses:

17

Je pense qu'il voulait dire que vous devriez utiliser l'injection de dépendances pour injecter une seule instance du service, au lieu d'utiliser l'implémentation Singleton classique avec un accesseur statique MySingleton.Instance.

public class MySingleton
{
    public static MySingleton Instance{get{...}};
}

Avec l'implémentation singleton classique, tout votre code dépend du fait que ce service soit un singleton. Vous codez essentiellement cette hypothèse en consommant du code chaque fois que vous utilisez MySingleton.Instance.

D'un autre côté, avec DI, vous obtenez une instance du service transmise à votre constructeur et la stockez. Qu'il n'y ait qu'une seule instance de ce service est un détail d'implémentation. Vous pouvez facilement le modifier pour donner au code consommateur une instance différente. De cette façon, vous avez une classe / interface qui est implémentée par une seule instance, au lieu d'imposer qu'il n'y a qu'une seule instance.

Ceci est utile si, par exemple, vous voulez une implémentation simulée du service pour les tests, ou si différentes parties du programme nécessitent des configurations différentes de ce service.

CodesInChaos
la source
4

Oui, tu as raison. Au lieu d'accéder à l'objet via le singleton, vous lui passez une référence, vous utilisez donc une injection de constructeur.

Ce que d'autres soulignent, c'est que ces notions ne sont pas liées. Consommer une instance singleton n'a rien de spécial car l'objet vers lequel vous injectez ne se soucie pas vraiment d'où vient l'objet injecté.

Wiktor Zychla
la source
3

Il y a un cas où le motif Singleton et DI / IoC se croisent - l'injection d'un Singleton.

La plupart des infrastructures DI peuvent être configurées pour instancier une seule instance d'un objet injecté. Tout objet consommateur qui demande une instance d'un tel objet obtiendra la même instance unique. Cette instance est par définition un Singleton. C'est à peu près tout pour le concept de chevauchement.

Dave
la source
2

La confusion ici est que deux concepts ont été confondus: le singleton et l'accesseur / passerelle statique vers l'instance singleton.

Comme vous l'avez identifié à juste titre, votre collègue propose que la dépendance soit injectée plutôt qu'accédée directement à l'aide de Singleton.Instance(passerelle statique).

La raison pour laquelle cela n'a rien à voir avec le motif singleton est que le même concept DI s'applique également à l'instanciation d'un objet non singleton avec new Foo(). La dépendance serait injectée indépendamment du fait qu'il s'agisse d'une implémentation singleton.

Geai
la source