Quando si utilizza l'iniezione di dipendenza quali dipendenze si inietta?Quali dipendenze dovrei iniettare?
ho precedentemente iniettato tutte le dipendenze ma hanno trovato quando fa TDD ci sono tipicamente due tipi di dipendenza:
- quelle che sono veri dipendenze esterne che possono variare per esempio ProductRepository
- Quelle che esistono puramente per testabilità, ad es. Parte del comportamento della classe che è stato estratto e iniettato solo per testability
Un approccio è quello di iniettare tutte le dipendenze come questo
public ClassWithExternalDependency(IExternalDependency external,
IExtractedForTestabilityDependency internal)
{
// assign dependencies ...
}
ma ho trovato questo può causare dipendenza gonfiare nel Registro DI.
Un altro approccio è quello di nascondere il "verificabilità delle dipendenze" come questo
public ClassWithExternalDependency(IExternalDependency external)
: this (external, new ConcreteClassOfInternalDependency())
{}
internal ClassWithExternalDependency(IExternalDependency external,
IExtractedForTestabilityDependency internal)
{
// assign dependencies ...
}
Si tratta di uno sforzo maggiore, ma sembra avere molto più senso. Lo svantaggio di non tutti gli oggetti sono configurati nel framework DI, rompendo così una "best practice" che ho sentito.
Quale approccio sosterreste e perché?
Uno dei vantaggi di invertire le dipendenze È essere in grado di testare le unità isolatamente. Posso estrarre una classe calcolatrice per testarla isolatamente ma forse non ha bisogno di iniettare (vedi secondo esempio di codice). Non ho potuto testarlo in-situ in quanto avrebbe gonfiato i test per il client della classe calcolatrice. – Alex
Iniettare tutti gli iniettabili, i nuovi tutti i nuovi. Senza questa distinzione, DI richiederebbe tutti gli oggetti che vivono per tutta la durata del programma. Le novità, ovvero i tipi di valore, rappresentano i dati inerti e, facoltativamente, alcuni comportamenti trasformativi associati (ovvero metodi che accettano valori e restituiscono nuovi valori). Gli iniettabili, ovvero i tipi di servizio/business, rappresentano la funzionalità e, facoltativamente, alcuni stati associati al programma. Probabilmente, abbiamo anche i tipi di I/O per rappresentare lo stato esterno, ad es. File(). I tipi di I/O devono essere nuovi, ma dovrebbero essere creati attraverso fabbriche astratte in modo da poter essere derisi per il test. – Jegschemesch