Prenderò un tack piuttosto diverso rispetto a CandiedOrange. Prima però, voglio andare oltre alcuni potenziali altri problemi. Non so se alcuni si applicano alla tua situazione, ma voglio coprire tutte le basi.
In primo luogo, non tutto deve essere iniettato. Le cose (concettualmente) senza dipendenze, in particolare oggetti valore e oggetti di trasferimento dati (DTO) non devono essere iniettati proprio come non si userebbe l'iniezione di dipendenza per iniettare un StringFactory
. In secondo luogo, non è necessario un factory se il costruttore di una classe non è parametrizzato ad eccezione delle dipendenze. Terzo, potrebbe darsi che troppe cose abbiano dipendenze e dovresti forse ristrutturare il tuo codice. Ad esempio, se i DTO devono assumere dipendenze per salvarsi, è possibile che tale comportamento venga spostato all'esterno del DTO in modo che non richieda alcuna dipendenza. In quarto luogo, come altri hanno menzionato, si può cadere in una trappola in cui si sta tentando di adattare le cose allo stampo del framework DI quando ciò non è né necessario né utile. A volte è semplicemente più semplice avere il codice che hai scritto per gestire parte del processo di risoluzione delle dipendenze nella "radice della composizione" principale.
Tuttavia, anche se nessuna delle situazioni precedenti si applica, puoi facilmente trovarti nella tua situazione. Considera un'analogia che non è un'analogia, ma esattamente ciò che sta sta accadendo. Diciamo che hai la seguente espressione usando le operazioni che sono state aggiunte con LINQ (che ho ottenuto da qui dopo aver cercato su google "esempio di linq", selezionando uno dei link in alto e selezionando a caso gli esempi su questo sito):
customers.SelectMany((cust, custIndex) =>
orders.Where(o => cust.Field("CustomerID") == o.Field("CustomerID"))
.Select(o => new { CustomerIndex = custIndex + 1, OrderID = o.Field("OrderID") }));
Ciò che fa non è importante. Ciò che è importante sono le tre funzioni lambda. Immagina, come sarebbe stato il caso in C # 1.0, che dovevi usare il Pattern della strategia e creare una classe per ognuno di quei lambda. Sarebbe osceno, non lo faresti, e nella misura in cui sei stato costretto a farlo, sicuramente "inquinerà" il tuo progetto. Il modello di fabbrica è solo il modello di strategia applicato alla creazione dell'oggetto. Infatti, se pensi, ad esempio, al costruttore Person
come Func<Dependencies, Parameters, Person>
, un PersonFactory
di base è proprio ciò che ottieni dal curriculum, ovvero un Func<Dependencies, Func<Parameters, Person>>
. Quello che vuoi veramente in una classe che ha bisogno di creare Person
s è la parte Func<Parameters, Person>
, e vuoi un'integrazione delle dipendenze per gestire le dipendenze.
Se non si utilizza affatto un framework di dipendenza delle dipendenze e si sono semplicemente cablate manualmente le dipendenze nella root principale / della composizione, si può semplicemente dipendere da Func<Parameters, Person>
(o meglio Func<Parameters, IPerson>
) e semplicemente passare un appropriato funzione lambda durante il cablaggio. Tuttavia, molti framework DI rendono questo difficile o impossibile. Il risultato è che, per questo scopo, sei di nuovo nella situazione di C # 1.0. (Questo è uno dei motivi per cui, personalmente, non sono così appassionato di framework DI [da non confondere con DI in sé], specialmente quelli con file di configurazione.)
È possibile eliminare molte delle classi factory usando l'intuizione di cui sopra, ma molto probabilmente questo sarà contorto per adattarsi al framework DI e quindi non ne vale la pena. Non eri chiaro di quale "inquinamento" ti preoccupi veramente: inquinamento delle directory, inquinamento da namespace, inquinamento Intellisense? Per gli ultimi due, il meccanismo di namespace di C # può gestirlo in modo adeguato. Per il primo, una directory è una soluzione ragionevole. Quale approccio ha più senso dipende dalla struttura della directory che stai utilizzando. Ad esempio, se ogni "entità" / "servizio" ha una propria directory, allora non c'è davvero un problema. Se si dispone di una cartella "Entità", quindi di una sottocartella per le interfacce di fabbrica e, forse, alcune o tutte le implementazioni di fabbrica sembrano ragionevoli.