Ich habe gehört, dass ich die Abhängigkeitsinjektion über Singleton für meinen Kollegen verwendet habe. Ich kann immer noch nicht erkennen, ob es sich um zwei orthogonale Muster handelt, die gegeneinander ausgetauscht werden können. Oder ist DI eine Methode, um das Singleton-Muster testbar zu machen?
Bitte schauen Sie sich das folgende Code-Snippet an.
IMathFace obj = Singleton.Instance;
SingletonConsumer singConsumer = new SingletonConsumer(obj);
singConsumer.ConsumerAdd(10,20);
Der SingletonConsumer
akzeptiert einen Parameter vom Typ IMathFace
. Anstatt intern auf die Singleton-Klasse zuzugreifen, SingletonConsumer
wird die Singleton-Instanz vom Aufrufer übergeben. Ist dies ein gutes Beispiel für die Verwendung von Singleton-Klassen über die Abhängigkeitsinjektion?
c#
architecture
singleton
Logeeks
quelle
quelle
Antworten:
Ich denke, er meinte, dass Sie Abhängigkeitsinjektion verwenden sollten, um eine einzelne Instanz des Dienstes zu injizieren, anstatt die klassische Singleton-Implementierung mit einem statischen Accessor zu verwenden
MySingleton.Instance
.Bei der klassischen Singleton-Implementierung hängt Ihr gesamter Code davon ab, dass dieser Dienst ein Singleton ist. Sie programmieren diese Annahme grundsätzlich fest in konsumierenden Code, wann immer Sie sie verwenden
MySingleton.Instance
.Andererseits erhalten Sie mit DI eine Instanz des Dienstes, die an Ihren Konstruktor übergeben und dort gespeichert wird. Dass es nur eine einzige Instanz dieses Dienstes gibt, ist ein Implementierungsdetail. Sie können es leicht ändern, um dem konsumierenden Code eine andere Instanz zu geben. Auf diese Weise haben Sie eine Klasse / Schnittstelle, die zufällig von einer einzelnen Instanz implementiert wird, anstatt zu erzwingen, dass es nur eine Instanz gibt.
Dies ist nützlich, wenn Sie beispielsweise eine Scheinimplementierung des Dienstes zum Testen wünschen oder wenn verschiedene Teile des Programms unterschiedliche Konfigurationen dieses Dienstes benötigen.
quelle
Ja, du hast recht. Anstatt über den Singleton auf das Objekt zuzugreifen, übergeben Sie einen Verweis darauf, sodass Sie eine Konstruktorinjektion verwenden.
Andere weisen darauf hin, dass diese Begriffe nicht miteinander zusammenhängen. Das Konsumieren einer Singleton-Instanz ist nichts Besonderes, da es dem Objekt, in das Sie injizieren, egal ist, woher das injizierte Objekt stammt.
quelle
Es gibt einen Fall, in dem das Singleton-Muster und DI / IoC die Injektion eines Singleton schneiden.
Die meisten DI-Frameworks können so konfiguriert werden, dass sie eine einzelne Instanz eines injizierten Objekts instanziieren. Jedes Consumer-Objekt, das eine Instanz eines solchen Objekts anfordert, erhält dieselbe einzelne Instanz. Diese Instanz ist per Definition ein Singleton. Das war's schon mit der Überlappung im Konzept.
quelle
Die Verwirrung hier ist, dass zwei Konzepte zusammengeführt wurden: der Singleton und der statische Accessor / Gateway zur Singleton-Instanz.
Wie Sie zu Recht festgestellt haben, schlägt Ihr Kollege vor, die Abhängigkeit einzuschleusen, anstatt direkt über
Singleton.Instance
(statisches Gateway) darauf zuzugreifen.Der Grund dafür, dass dies mit dem Singleton-Muster eigentlich nichts zu tun hat, ist, dass dasselbe DI-Konzept auch für die Instanziierung eines Nicht-Singleton-Objekts mit gilt
new Foo()
. Die Abhängigkeit wird unabhängig davon injiziert, ob es sich um eine Singleton-Implementierung handelt.quelle