2010-01-03 19 views
46

Ho deciso di utilizzare i principi IoC su un progetto più grande. Tuttavia, mi piacerebbe ottenere qualcosa di dritto che mi dava fastidio da molto tempo. La conclusione che ho trovato è che un contenitore IoC è un modello architettonico, non un modello di progettazione. In altre parole, nessuna classe dovrebbe essere consapevole della sua presenza e il contenitore stesso dovrebbe essere usato a livello di applicazione per ricucire tutti i componenti. Essenzialmente, diventa un'opzione, oltre a un modello orientato agli oggetti ben progettato. Detto questo, come è possibile accedere a tipi risolti senza sprecare contenitori IoC ovunque (indipendentemente dal fatto che siano astratti o meno)? L'unica opzione che vedo qui è quella di utilizzare fabbriche astratte che usano un contenitore IoC per risolvere tipi concreti. Questo dovrebbe essere abbastanza facile da sostituire per una serie di fabbriche standard. è un buon approccio? Qualcuno qui ha usato e quanto bene ha funzionato per te? C'è qualcos'altro disponibile?Modello di fabbrica astratto in cima a IoC?

Grazie!

risposta

69

Come avete già capito, Dipendenza Iniezione (DI) stessa è solo una raccolta di schemi e tecniche.

Alla radice dell'applicazione vengono cablati tutti i grafici degli oggetti necessari. Questo posto è chiamato Composizione Root, e possiamo usare un contenitore DI per fare questo cablaggio per noi, oppure possiamo farlo manualmente (di Poor Man DI).

Il punto è che nell'applicazione è presente un solo punto in cui vi è un forte riferimento a un particolare componente tecnologico (il contenitore DI). Il resto della app è beatamente ignaro di come l'oggetto grafico è stato cablato - tutto ciò che conta è che tutte le dipendenze richieste sono state correttamente iniettati (ed è possibile utilizzare Constructor iniezione con Null Guardie per garantire che sia così).

Il Abstract Factory modello è un modello utile molto quando si tratta di DI. In pratica, usa Fabbrica astratta quando:

  • È necessario fornire uno o più parametri noti solo in fase di esecuzione prima di poter risolvere una dipendenza.
  • La durata della dipendenza è concettualmente inferiore alla durata del consumatore.

esempi e ulteriori informazioni sono disponibili qui:

+1

Penso di esserci quasi. Resta con me qui :) Diciamo solo che ho un'interfaccia IFruit che è implementata dalla classe Apple. Dopo aver registrato questo tipo concreto, voglio usarlo nel mio evento click sui pulsanti in un Windows Form. Come potrei arrivare in classe Apple senza accedere esplicitamente al contenitore IoC dall'evento button? –

+7

Dipende da: ci sono molte istanze di IFruit nella tua app o solo una? Se ce n'è solo uno, dovrebbe già essere iniettato nella classe con il gestore di clic del pulsante. Se ce ne sono molti, è molto probabile che sia necessario un IFruitFactory in grado di creare un'istanza di IFruit da altri valori di runtime. In quest'ultimo caso, IFruitFactory sarebbe la dipendenza iniettata. –

+0

Considerando che esiste solo un'istanza di IFruit, l'unico modo in cui vedo che viene iniettato nella classe Form con l'evento click del pulsante è se cambio il costruttore di moduli per includere l'interfaccia di IFruit e quindi registro il modulo stesso con il contenitore IoC per eseguire il costruttore iniezione. Questo suono è corretto? Grazie per l'aiuto! –

4

Nella maggior parte delle parti dell'applicazione è necessaria una classe Bootstrap che carica il contesto IOC. Questo contesto fornirà quindi gli oggetti effettivamente istanziati e quindi agirà come una fabbrica.

Ma questo dovrebbe accadere solo con pochissimi oggetti e l'utente della classe Bootstrap/Factory dovrebbe conoscere il meno possibile l'architettura sottostante. Ad esempio se hai configurato un oggetto server HTTP completamente tramite IOC e vuoi avviarlo, la tua classe Bootstrap deve solo fornire un metodo getHttpServer(). Quindi il metodo principale del tuo programma deve solo chiamare Bootstrap.getHttpServer(). Start() per farlo funzionare.

Il cablaggio degli altri oggetti è già stato eseguito dal contesto dell'applicazione, ad es. si configura l'Oggetto A tramite IOC che fa parte dell'oggetto B, quindi si configura l'Oggetto B con il riferimento all'Oggetto A. Nessuno di questi di solito ha bisogno di conoscere né il contenitore né la fabbrica.

Problemi correlati