Dipendenza Iniezione e Singleton. Sono due concetti completamente diversi?


17

Ho sentito parlare dell'utilizzo dell'iniezione di dipendenza su Singleton per il mio collega. Non riesco ancora a capire se sono due schemi ortogonali che possono essere sostituiti tra loro? O DI è un metodo per rendere testabile il modello Singleton?

Dai un'occhiata al seguente frammento di codice.

    IMathFace obj = Singleton.Instance;

    SingletonConsumer singConsumer = new SingletonConsumer(obj);

    singConsumer.ConsumerAdd(10,20);

Il SingletonConsumerè accettare un parametro di tipo IMathFace. Invece di accedere internamente alla classe singleton, SingletonConsumerriceverà l'istanza singleton dal chiamante. È un buon esempio di consumo della classe singleton tramite l'iniezione delle dipendenze?


Potete per favore dirmi come DI può sostituire il singleton?

7
Singleton è un modello di progettazione. DI / IoC è una tecnica.
Dave, il

2
DI non può sostituire Singleton non più di quanto una banana potrebbe sostituire un carburatore. Sono concetti completamente diversi.
Dave, il

quindi il mio esempio è valido.

1
Sì, ma può venire a scapito dell'incapsulamento (che è vero anche per i non singleton) vedi: stackoverflow.com/questions/1005473/…

Risposte:


17

Penso che intendesse usare l'iniezione di dipendenza per iniettare una singola istanza del servizio, invece di usare l'implementazione classica di Singleton con un accessore statico MySingleton.Instance.

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

Con la classica implementazione singleton tutto il tuo codice dipende dal fatto che quel servizio sia un singleton. Fondamentalmente decodifichi tale presupposto nel consumo di codice ogni volta che lo usi MySingleton.Instance.

D'altra parte con DI ottieni un'istanza del servizio passata al tuo costruttore e la memorizzi. Che esiste solo una singola istanza di questo servizio è un dettaglio di implementazione. Puoi facilmente cambiarlo per dare al codice che consuma un'istanza diversa. In questo modo hai qualche classe / interfaccia che sembra essere implementata da una singola istanza, invece di imporre che ci sia solo un'istanza.

Ciò è utile se, ad esempio, si desidera un'implementazione fittizia del servizio per i test o se parti diverse del programma necessitano di configurazioni diverse di quel servizio.


4

Si hai ragione. Invece di accedere all'oggetto tramite il singleton, stai passando un riferimento ad esso, quindi stai usando un'iniezione del costruttore.

Ciò che altri sottolineano è che queste nozioni non sono correlate. Il consumo di un'istanza singleton non è niente di speciale in quanto l'oggetto a cui si sta iniettando non si preoccupa realmente della provenienza dell'oggetto iniettato.


2

C'è un caso in cui il modello Singleton e DI / IoC si intersecano: l'iniezione di un Singleton.

La maggior parte dei framework DI può essere configurata per creare un'istanza di una singola istanza di un oggetto iniettato. Qualsiasi oggetto consumatore che richiede un'istanza di tale oggetto otterrà la stessa singola istanza. Quell'istanza è per definizione una Singleton. Questo è tutto per la sovrapposizione nel concetto.


1

La confusione qui è che due concetti sono stati combinati: il singleton e il accessor / gateway statico all'istanza singleton.

Come hai giustamente identificato, il tuo collega sta suggerendo di iniettare la dipendenza anziché accedervi direttamente tramite Singleton.Instance(gateway statico).

Il motivo per cui questo non ha nulla a che fare con il modello singleton è che lo stesso concetto DI si applica ugualmente all'istanza di un oggetto non singleton new Foo(). La dipendenza verrebbe iniettata indipendentemente dal fatto che si tratti di un'implementazione singleton.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.