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 SingletonConsumer
está aceitando um parâmetro do tipo IMathFace
. Em vez de acessar a classe singleton internamente, SingletonConsumer
a instância singleton passará pelo chamador. Este é um bom exemplo de consumo de classe singleton por injeção de dependência?
c#
architecture
singleton
logeeks
fonte
fonte
Respostas:
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
.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.
fonte
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.
fonte
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.
fonte
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.fonte