Estrictamente hablando, la Inyección de dependencias solo se opone realmente a NO la Inyección de dependencias y, por lo tanto, a cualquier estrategia de administración de dependencias que no sea Inyección de dependencias.
El acoplamiento [no deseado], aunque no es exactamente un problema ortogonal, puede ocurrir o mitigarse de cualquier manera. Ambos están acoplados a DependencyClass:
public DependencyInjectedConstructor(DependencyClass dep) {
dep.do();
}
public DependencyLookupConstructor() {
var dep = new DependencyClass();
dep.do();
}
DependencyLookupConstructorestá acoplado a un particular DependencyClassen este caso. Sin embargo, son ambos acoplados a DependencyClass. El verdadero mal, si hay uno aquí, no es necesariamente el acoplamiento, es que DependencyLookupConstructordebe cambiar si de DependencyClassrepente necesita inyectar sus propias dependencias 1 .
Sin embargo, este constructor / clase está aún más débilmente acoplado:
public DependencyLocatingConstructor() {
var dep = ServiceLocator.GetMyDoer();
dep.do();
}
Si está trabajando en C #, lo anterior permitan que el ServiceLocatorregresar nada cuando GetMyDoer()se invoca, con tal de que tiene puede do()lo que DependencyLocatingConstructorlo tiene do(). Obtiene el beneficio de la validación de firma en tiempo de compilación sin siquiera estar acoplado a una interfaz completa 2 .
Entonces, elige tu veneno.
Pero, básicamente, si hay un "opuesto" concreto de la Inyección de dependencias, sería algo más en el ámbito de las "Estrategias de gestión de dependencias". Entre otros, si utilizó alguno de los siguientes en la conversación, lo reconocería como NO una inyección de dependencia:
- Patrón de localizador de servicio
- Localizador de dependencia / ubicación
- Construcción directa de objeto / dependencia
- Dependencia oculta
- "No inyección de dependencia"
1. Irónicamente, algunos de los problemas que DI resuelve en niveles más altos son el resultado de [sobre-] usar DI en los niveles más bajos. He tenido el placer de trabajar en bases de código con una complejidad innecesaria en todas partes como resultado de acomodar el puñado de lugares donde esa complejidad realmente ayudó ... Estoy ciertamente predispuesto por la mala exposición.
2. El uso de la ubicación del servicio también le permite especificar fácilmente diferentes dependencias del mismo tipo por su función funcional del código de invocación , mientras sigue siendo en gran medida agnóstico sobre cómo se construye la dependencia. Suponga que necesita resolver Usero IUserpara diferentes propósitos: por ejemplo, Locator.GetAdministrator()versus Locator.GetAuthor(), o lo que sea. Mi código puede preguntar qué necesita funcionalmente sin siquiera saber qué interfaces admite.