Nel mio ultimo grande progetto, ho usato molto l'iniezione di dipendenza. Ho iniziato a utilizzare l'iniezione del costruttore, ma anche due o tre dipendenze hanno portato a un codice davvero brutto.
public MyClass(
IDependency1 dependency1,
IDependency2 dependency2
IDependency3 dependency3)
Non sono un fan dell'iniezione di proprietà. Alcune persone dicono che implica una dipendenza "opzionale". Penso che quello che intendono è che ci sarà una dipendenza predefinita (la classe di produzione) ma può essere sostituita con un oggetto mock durante il test. Molte volte, anche le mie dipendenze hanno dipendenze, quindi non posso fornire un valore predefinito a meno che non abbia usato un singleton o qualcosa del genere. Il mio problema con l'iniezione di proprietà è che preferisco oggetti completamente inizializzati e non voglio dimenticarmi accidentalmente di prendere in giro una dipendenza durante il test.
Quindi, ho trovato un compromesso. Ho creato un "oggetto parametro" che aveva proprietà per tutte le mie dipendenze. Li ho passati ai miei costruttori. Questo ha avuto il vantaggio di mantenere il mio codice un po 'più pulito e Potrei ignorare alcune dipendenze durante il test se non sono state toccate.
In base al feedback, ho avuto l'impressione che fosse una cattiva idea. È stata un'iniezione del costruttore o l'iniezione di parametri - nessun compromesso consentito. In seguito mi sono reso conto che questi oggetti parametro a volte divennero le loro classi (o serie di classi).
Ecco quando ho scoperto un modello interessante. Molti oggetti business dipendevano da altri oggetti business, che avevano le loro dipendenze. Quello che ho trovato era un'interessante struttura dati, simile a un elenco collegato.
Questastrutturadatipotrebbediventarepiuttostocomplessaasecondadelnumerodiclassicheinteragiscono.Nellamaggiorpartedeicasi,lastrutturaerapiùvicinaaunalberon-ario.Ognioggettoparametropuòesserecollegatoaqualsiasinumerodialtrioggetti(inclusialtrioggettibusiness).Glioggettibusinesseranoinodidell'alberoeglioggettiparametroeranocomeibordichelicollegavano.
Penso che connettere tutti questi oggetti insieme senza usare una struttura di iniezione dichiarativa delle dipendenze sarebbe sconvolgente. Il framework di iniezione delle dipendenze che stavo usando andava a 8 livelli nel mio codice, costruendo le dipendenze dal basso verso l'alto nel peggiore dei casi.
Gli oggetti parametro di solito mostrano solo le dipendenze. In rare occasioni, li nascondevo dietro le chiamate alle funzioni amiche e li rendevo i loro oggetti di business (di solito ne risultava un altro oggetto parametrico). Dovevo ricordare a me stesso che gli oggetti parametro esistevano solo perché non volevo costruire dipendenze nel costruttore (o passarle al costruttore). Aveva senso solo creare nuovi oggetti di business quando ho iniziato a ripetermi. Anche allora, ho finito con un'esplosione di oggetti parametrici.
Ho letto molti libri che spiegano che questa situazione non dovrebbe mai accadere. Le classi dovrebbero avere pochissime dipendenze. Era un segno che le mie classi facevano "troppo". Ma nella maggior parte di questi casi, un oggetto business utilizzava dati da più tabelle di database (repository), impostazioni di configurazione, servizi, ecc. Per calcolare qualcosa. Ciò si è verificato più spesso quando si implementava una serie di passaggi che costituiscono un'unità di lavoro. Quando sono necessarie N cose per fare un compito, il meglio che puoi fare è spingere quelle N cose ad altre classi o in cima allo stack delle chiamate. Una classe con 6 dipendenze è migliore o peggiore di 3 classi con due dipendenze ciascuna?
Spero di ottenere un feedback su questo approccio all'iniezione delle dipendenze, in relazione a come progettare un livello aziendale.