A injeção de construtor tem a vantagem de explicitar a dependência e forçar o cliente a fornecer uma instância. Também pode garantir que o cliente não possa alterar a instância posteriormente. Uma (possível) desvantagem é que você precisa adicionar um parâmetro ao seu construtor.
A Injeção de Setter tem a vantagem de não exigir a adição de um parâmetro ao construtor. Também não requer que o cliente defina a instância. Isso é útil para dependências opcionais. Isso também pode ser útil se você desejar que a classe crie, por exemplo, um repositório de dados real por padrão e, em um teste, você pode usar o configurador para substituí-lo por uma instância de teste.
A injeção de interface , até onde eu sei, não é muito diferente da injeção de incubadora. Nos dois casos, você está (opcionalmente) configurando uma dependência que pode ser alterada posteriormente.
Em última análise, é uma questão de preferência e se é necessária ou não uma dependência . Pessoalmente, uso quase exclusivamente a injeção de construtores. Eu gosto que ele explique as dependências de uma classe, forçando o cliente a fornecer uma instância no construtor. Também gosto que o cliente não possa alterar a instância após o fato.
Muitas vezes, minha única razão para passar em duas implementações separadas é para testar. Na produção, posso passar em a DataRepository
, mas nos testes, em FakeDataRepository
. Nesse caso, geralmente fornecerei dois construtores: um sem parâmetros e outro que aceita a IDataRepository
. Então, no construtor sem parâmetros, encadeará uma chamada para o segundo construtor e passarei a new DataRepository()
.
Aqui está um exemplo em c #:
public class Foo
{
private readonly IDataRepository dataRepository;
public Foo() : this(new DataRepository())
{
}
public Foo(IDataRespository dataRepository)
{
this.dataRepository = dataRepository;
}
}
Isso é conhecido como Injeção de Dependência do Pobre Homem. Gosto porque, no código do cliente de produção, não preciso me repetir tendo várias instruções repetidas que parecem
var foo = new Foo(new DataRepository());
No entanto, ainda posso passar em uma implementação alternativa para teste. Percebo que, com o DI do Poor Man, estou codificando minha dependência, mas isso é aceitável para mim, pois eu o uso principalmente para testes.