A rigor di termini, l' iniezione di dipendenza si oppone davvero NON a iniezione di dipendenza - e quindi a qualsiasi strategia di gestione delle dipendenze che non sia iniezione di dipendenza.
L'accoppiamento [indesiderato], sebbene non esattamente un problema ortogonale, può verificarsi o essere mitigato in entrambi i modi. Entrambi sono accoppiati a DependencyClass
:
public DependencyInjectedConstructor(DependencyClass dep) {
dep.do();
}
public DependencyLookupConstructor() {
var dep = new DependencyClass();
dep.do();
}
DependencyLookupConstructor
è accoppiato a un particolare DependencyClass
in questo caso. Ma sono entrambi accoppiati a DependencyClass
. Il vero male, se ce n'è uno qui, non è necessariamente l'accoppiamento, è che DependencyLookupConstructor
deve cambiare se DependencyClass
improvvisamente ha bisogno delle sue dipendenze iniettate 1 .
Tuttavia, questo costruttore / classe è ancora più liberamente accoppiato:
public DependencyLocatingConstructor() {
var dep = ServiceLocator.GetMyDoer();
dep.do();
}
Se lavori in C #, quanto sopra ti consentirà ServiceLocator
di restituire qualsiasi cosa quando GetMyDoer()
viene invocata, a patto che abbia do()
ciò che DependencyLocatingConstructor
ha do()
. Ottieni il vantaggio della convalida della firma in fase di compilazione senza nemmeno essere accoppiato a un'interfaccia completa 2 .
Quindi, scegli il tuo veleno.
Ma fondamentalmente, se esiste un "opposto" concreto dell'iniezione di dipendenza, sarebbe qualcos'altro nel regno delle "strategie di gestione delle dipendenze". Tra l'altro, se hai usato uno dei seguenti argomenti nella conversazione, lo riconoscerei come NON Iniezione di dipendenza:
- Pattern di localizzazione di servizio
- Localizzatore / posizione delle dipendenze
- Costruzione diretta di oggetti / dipendenze
- Dipendenza nascosta
- "Iniezione non dipendente"
1. Ironia della sorte, alcuni dei problemi che DI risolve ai livelli più alti sono una sorta di risultato di [over-] utilizzo di DI nei livelli inferiori. Ho avuto il piacere di lavorare su basi di codice con complessità inutile dappertutto a causa dell'accoglienza di una manciata di posti in cui quella complessità ha effettivamente aiutato ... Sono certamente influenzato da una cattiva esposizione.
2. L'utilizzo dell'ubicazione del servizio consente inoltre di specificare facilmente dipendenze diverse dello stesso tipo in base al loro ruolo funzionale rispetto al codice di invocazione , pur essendo in gran parte agnostico su come viene costruita la dipendenza. Supponiamo di dover risolvere User
o IUser
per scopi diversi: ad esempio, Locator.GetAdministrator()
contro Locator.GetAuthor()
- o qualsiasi altra cosa. Il mio codice può chiedere di cosa ha bisogno funzionalmente senza nemmeno sapere quali interfacce supporta.