Inyección de dependencias y Singleton. ¿Son dos conceptos completamente diferentes?

17

He escuchado sobre el uso de la inyección de dependencia sobre Singleton para mi colega. ¿Todavía no puedo distinguir si son dos patrones ortogonales que se pueden reemplazar entre sí? ¿O es DI un método para hacer que el patrón Singleton sea comprobable?

Eche un vistazo al siguiente fragmento de código.

    IMathFace obj = Singleton.Instance;

    SingletonConsumer singConsumer = new SingletonConsumer(obj);

    singConsumer.ConsumerAdd(10,20);

El SingletonConsumerestá aceptando un parámetro de tipo IMathFace. En lugar de acceder a la clase singleton internamente, SingletonConsumerla persona que llama pasará la instancia singleton. ¿Es este un buen ejemplo de consumo de clase singleton mediante inyección de dependencia?

logeeks
fuente
¿Me puede decir cómo DI puede reemplazar el singleton?
77
Singleton es un patrón de diseño. DI / IoC es una técnica.
Dave
2
DI no puede reemplazar a Singleton más de lo que un plátano podría reemplazar a un carburador. Son conceptos completamente diferentes.
Dave
Entonces mi ejemplo es válido.
1
Sí, pero puede venir a expensas de la encapsulación (que también es cierto para los no solteros), consulte: stackoverflow.com/questions/1005473/…

Respuestas:

17

Creo que quería decir que debería usar la inyección de dependencia para inyectar una sola instancia del servicio, en lugar de usar la implementación clásica de Singleton con un descriptor de acceso estático MySingleton.Instance.

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

Con la implementación clásica de singleton, todo su código depende de que ese servicio sea un singleton. Básicamente codifica esa suposición para consumir código cada vez que la usa MySingleton.Instance.

Por otro lado, con DI obtienes una instancia del servicio pasado a tu constructor y lo almacenas. Que solo haya una única instancia de este servicio es un detalle de implementación. Puede cambiarlo fácilmente para darle al código consumidor una instancia diferente. De esa manera, tiene alguna clase / interfaz que implementa una sola instancia, en lugar de exigir que solo haya una instancia.

Esto es útil si, por ejemplo, desea una implementación simulada del servicio para la prueba, o si diferentes partes del programa necesitan diferentes configuraciones de ese servicio.

CodesInChaos
fuente
4

Sí, tiene usted razón. En lugar de acceder al objeto a través del singleton, le está pasando una referencia, por lo tanto, está utilizando una inyección de constructor.

Lo que otros señalan es que estas nociones no están relacionadas. Consumir una instancia singleton no es nada especial ya que el objeto al que está inyectando realmente no le importa de dónde proviene el objeto inyectado.

Wiktor Zychla
fuente
2

Hay un caso en el que el patrón Singleton y DI / IoC se cruzan: la inyección de un Singleton.

La mayoría de los marcos DI se pueden configurar para crear una instancia de un objeto inyectado. Cualquier objeto de consumidor que solicite una instancia de dicho objeto obtendrá la misma instancia única. Esa instancia es, por definición, un Singleton. Eso es todo por la superposición de conceptos.

Dave
fuente
1

La confusión aquí es que se han combinado dos conceptos: el singleton y el acceso estático / puerta de enlace a la instancia de singleton.

Como ha identificado correctamente, su colega sugiere que se inyecte la dependencia en lugar de acceder directamente mediante Singleton.Instance(puerta de enlace estática).

La razón por la que esto no tiene nada que ver realmente con el patrón singleton es que el mismo concepto DI se aplica igualmente a la instanciación de un objeto no singleton con new Foo(). La dependencia se inyectaría independientemente de si se trata de una implementación singleton.

Arrendajo
fuente