Injeção de Dependência e Singleton. São dois conceitos completamente diferentes?


17

Eu tenho ouvido falar sobre o uso da injeção de dependência sobre Singleton para meu colega. Ainda não consigo entender se são dois padrões ortogonais que podem ser substituídos um pelo outro? Ou o DI é um método para tornar o padrão Singleton testável?

Dê uma olhada no seguinte trecho de código.

    IMathFace obj = Singleton.Instance;

    SingletonConsumer singConsumer = new SingletonConsumer(obj);

    singConsumer.ConsumerAdd(10,20);

O SingletonConsumerestá aceitando um parâmetro do tipo IMathFace. Em vez de acessar a classe singleton internamente, SingletonConsumera instância singleton passará pelo chamador. Este é um bom exemplo de consumo de classe singleton por injeção de dependência?


Você pode me dizer como o DI pode substituir o singleton?

7
Singleton é um padrão de design. DI / IoC é uma técnica.
Dave

2
O DI não pode substituir Singleton da mesma forma que uma banana poderia substituir um carburador. Eles são conceitos completamente diferentes.
Dave

então meu exemplo é válido.

1
Sim, mas pode custar o encapsulamento (o que também é verdadeiro para os não-singleton): stackoverflow.com/questions/1005473/…

Respostas:


17

Acho que ele quis dizer que você deve usar injeção de dependência para injetar uma única instância do serviço, em vez de usar a implementação clássica de Singleton com um acessador estático MySingleton.Instance.

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

Com a implementação clássica de singleton, todo o seu código depende desse serviço ser um singleton. Você basicamente codifica essa suposição para consumir código sempre que usar MySingleton.Instance.

Por outro lado, com o DI, você obtém uma instância do serviço passada no seu construtor e o armazena. O fato de haver apenas uma instância desse serviço é um detalhe da implementação. Você pode alterá-lo facilmente para fornecer ao código consumidor uma instância diferente. Dessa forma, você tem alguma classe / interface que é implementada por uma única instância, em vez de impor que exista apenas uma instância.

Isso é útil se você, por exemplo, desejar uma implementação simulada do serviço para teste ou se partes diferentes do programa precisarem de configurações diferentes desse serviço.


4

Sim você está certo. Em vez de acessar o objeto por meio do singleton, você está passando uma referência a ele, portanto, usando uma injeção de construtor.

O que outros apontam é que essas noções não estão relacionadas. Consumir uma instância singleton não é nada de especial, pois o objeto ao qual você está injetando não se importa de onde vem o objeto injetado.


2

Há um caso em que o padrão Singleton e o DI / IoC se cruzam - a injeção de um Singleton.

A maioria das estruturas de DI pode ser configurada para instanciar uma única instância de um objeto injetado. Qualquer objeto consumidor que solicite uma instância desse objeto terá a mesma instância única. Essa instância é, por definição, um Singleton. Isso é tudo sobre a sobreposição de conceito.


1

A confusão aqui é que dois conceitos foram confundidos: o singleton e o acessador / gateway estático para a instância do singleton.

Como você corretamente identificou, seu colega está sugerindo que a dependência seja injetada em vez de acessada diretamente usando Singleton.Instance(gateway estático).

A razão pela qual isso não tem nada a ver com o padrão singleton é que o mesmo conceito de DI se aplica igualmente à instanciação de um objeto não singleton new Foo(). A dependência seria injetada independentemente de se tratar de uma implementação única.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.