A rigor, a Injeção de Dependência realmente não se opõe à Injeção de Dependência - e, portanto, a qualquer estratégia de gerenciamento de dependência que não seja a Injeção de Dependência.
O acoplamento [indesejado], embora não seja exatamente um problema ortogonal, pode ocorrer ou ser mitigado de qualquer maneira. Ambos são acoplados a DependencyClass
:
public DependencyInjectedConstructor(DependencyClass dep) {
dep.do();
}
public DependencyLookupConstructor() {
var dep = new DependencyClass();
dep.do();
}
DependencyLookupConstructor
é acoplado a um particular DependencyClass
neste caso. Mas, ambos estão acoplados DependencyClass
. O verdadeiro mal, se houver um aqui, não é necessariamente o acoplamento, é que DependencyLookupConstructor
precisa mudar se de DependencyClass
repente precisar de suas próprias dependências injetadas 1 .
No entanto, esse construtor / classe é ainda mais frouxamente acoplado:
public DependencyLocatingConstructor() {
var dep = ServiceLocator.GetMyDoer();
dep.do();
}
Se você estiver trabalhando em C #, o acima permitirá que você ServiceLocator
retorne qualquer coisa quando GetMyDoer()
for chamada, desde que possua o do()
que a DependencyLocatingConstructor
possui do()
. Você obtém o benefício da validação de assinatura em tempo de compilação sem precisar ser acoplado a uma interface completa 2 .
Então, escolha seu veneno.
Mas, basicamente, se houver um "oposto" concreto da injeção de dependência, seria outra coisa no campo das "Estratégias de gerenciamento de dependência". Entre outros, se você usasse um dos seguintes itens na conversa, eu o reconheceria como sendo NÃO injeção de dependência:
- Padrão do Localizador de Serviço
- Localizador / Local de Dependência
- Construção direta de objeto / dependência
- Dependência oculta
- "Injeção sem dependência"
1. Ironicamente, alguns dos problemas que o DI resolve em níveis mais altos são como resultado do uso excessivo do DI nos níveis mais baixos. Tive o prazer de trabalhar em bases de código com complexidade desnecessária em todo o mundo, como resultado de acomodar vários lugares onde essa complexidade realmente ajudou ... Sou admitidamente influenciado por más exposições.
2. O uso da localização do serviço também permite que você especifique facilmente diferentes dependências do mesmo tipo por sua função funcional a partir do código de chamada , embora ainda seja bastante independente sobre como a dependência é construída. Suponha que você precise resolver User
ou IUser
para diferentes propósitos: por exemplo, Locator.GetAdministrator()
versus Locator.GetAuthor()
- ou o que for. Meu código pode solicitar o que ele precisa funcionalmente, mesmo sem saber quais interfaces ele suporta.