A chave dos contêineres DI é a abstração . Os contêineres DI abstraem essa preocupação de design para você. Como você pode imaginar, ele tem um impacto notável no código, muitas vezes traduzido em um número menor de construtores, montadores, fábricas e construtores. Em conseqüência, eles tornam seu código mais frouxamente acoplado (devido à IoC subjacente ), mais limpo e mais simples. Embora não sem um custo.
Planos de fundo
Anos atrás, essa abstração nos exigia escrever vários arquivos de configuração ( programação declarativa ). Foi fantástico ver o número de LOCs diminuindo substancialmente, mas enquanto os LOCSs diminuíram, o número de arquivos de configuração aumentou ligeiramente. Para projetos médios ou pequenos, não era um problema, mas para projetos maiores, a "montagem do código" dispersa em 50% entre os descritores de código e XML tornou-se uma dor de cabeça ... No entanto, o principal problema foi o paradigma em si. Foi bastante inflexível porque os descritores deixaram pouco espaço para personalizações.
O paradigma mudou progressivamente para a convenção sobre configuração , que troca os arquivos de configuração por anotações ou atributos. Ele mantém nosso código mais limpo e simples, fornecendo a flexibilidade que o XML não podia.
Provavelmente, essa é a diferença mais significativa em relação à forma como você estava trabalhando até agora. Menos código e mais mágica.
No lado negativo...
A convenção sobre configuração torna a abstração tão pesada que você mal sabe como ela funciona. Às vezes parece mágica e aqui vem mais uma desvantagem. Uma vez que está funcionando, muitos desenvolvedores não se preocupam com o funcionamento.
Esta é uma desvantagem para quem aprendeu DI com contêineres DI. Eles não entendem completamente a relevância dos padrões de design, as boas práticas e os princípios abstraídos pelo contêiner. Perguntei aos desenvolvedores se eles estavam familiarizados com o DI e suas vantagens e eles responderam: - Sim, eu usei o Spring IoC -. (O que diabos isso significa?!?)
Pode-se concordar ou não com cada uma dessas "desvantagens". Na minha humilde opinião, é necessário saber o que está acontecendo no seu projeto. Caso contrário, não temos um entendimento completo disso. Também é saber para que serve o DI e ter uma noção de como implementá-lo, é uma vantagem a considerar.
Do lado positivo...
Produtividade de uma palavra . As estruturas nos concentramos no que realmente importa. Os negócios do aplicativo.
Apesar das deficiências comentadas, para muitos de nós (cujo trabalho é condicionado por prazos e custos), essas ferramentas são um recurso inestimável. Na minha opinião, esse deve ser nosso principal argumento em favor da implementação de um contêiner de DI. Produtividade .
Teste
Se implementarmos DI puro ou contêineres, o teste não será um problema. Muito pelo contrário. Os mesmos contêineres geralmente nos fornecem as simulações para testes de unidade prontos para uso. Ao longo dos anos, usei meus testes como termômetros. Eles me dizem se eu confiei muito nas instalações de contêineres. Digo isso porque esses contêineres podem inicializar atributos privados sem setters ou construtores. Eles podem injetar componentes quase em qualquer lugar!
Parece tentador, certo? Seja cuidadoso! Não caia na armadilha !!
Sugestões
Se você decidir implementar contêineres, sugiro enfaticamente seguir as boas práticas. Continue implementando construtores, setters e interfaces. Aplique a estrutura / contêiner para usá-los . Facilitará possíveis migrações para outra estrutura ou remover a atual. Pode reduzir significativamente a dependência do contêiner.
Em relação a essas práticas:
Quando usar contêineres DI
Minha resposta será influenciada pela própria experiência, que é principalmente a favor dos contêineres DI (como eu comentei, estou muito focada na produtividade, então nunca tive a necessidade de DI puro. Muito pelo contrário).
Acho que você encontrará um artigo interessante de Mark Seeman sobre esse assunto, que também responde à pergunta sobre como implementar o DI puro .
Finalmente, se estivéssemos falando de Java, consideraria primeiro dar uma olhada no JSR330 - Injeção de Dependência .
Resumindo
Benefícios :
- Redução de custos e economia de tempo. Produtividade.
- Um número menor de componentes.
- O código se torna mais simples e limpo.
Desvantagens :
- O DI é delegado a bibliotecas de terceiros. Devemos estar cientes de seus compromissos, pontos fortes e fracos.
- Curva de aprendizado.
- Eles rapidamente fazem você esquecer alguns bons hábitos.
- Aumento das dependências do projeto (mais libs)
- Recipientes baseados em reflexão requerem mais recursos (memória). Isso é importante se estivermos limitados pelos recursos.
Diferenças com DI puro :
- Menos código e mais arquivos de configuração ou anotações.