Domanda

Attualmente sto scrivendo un SDK open source per un programma che utilizzo e sto utilizzando un contenitore IoC internamente (NInject) per collegare tutte le mie dipendenze interne.

Ho alcuni oggetti contrassegnati come interni in modo da non affollare l'API pubblica poiché vengono utilizzati solo internamente e non dovrebbero essere visti dall'utente, cose come fabbriche e altri oggetti. Il problema che sto riscontrando è che NInject non è in grado di creare oggetti interni, il che significa che devo contrassegnare come pubblici tutti i miei oggetti interni che ammucchiano l'API pubblica.

La mia domanda è: c'è un modo per aggirare questo problema o sto sbagliando tutto?

PS. Ho pensato di utilizzare l'attributo InternalsVisiableTo ma mi sembra che sia un po 'di odore.

È stato utile?

Soluzione

Occhiata veloce alle altre risposte: non sembra che tu stia facendo qualcosa di così diverso che c'è qualcosa di fondamentalmente sbagliato in Ninject che dovresti modificarlo o sostituirlo. In molti casi, non puoi " andare dritto per [gli] interni " perché si basano sull'iniezione di dipendenza non risolta; da qui l'utilizzo di Ninject. Inoltre sembra che tu abbia già un set interno di interfacce, motivo per cui è stata posta la domanda.

Pensieri: un problema con l'utilizzo di Ninject direttamente nell'SDK o nella libreria è che gli utenti dovranno utilizzare Ninject nel loro codice. Questo probabilmente non è un problema per te perché è la tua scelta IoC, quindi l'avresti usato comunque. E se vogliono usare un altro contenitore IoC, allora ora hanno effettivamente due sforzi per duplicare. Peggio ancora, se vogliono usare Ninject v2 e hai usato v1.5, questo complica davvero la situazione.

Caso migliore: se riesci a riformattare le tue classi in modo tale che ottengano tutto ciò di cui hanno bisogno tramite Iniezione delle dipendenze, questo è il più pulito perché il codice della libreria non ha bisogno di nessuna Contenitore IoC. L'app può collegare le dipendenze e scorre. Questo non è sempre possibile, poiché a volte le classi di libreria devono creare istanze con dipendenze che non è possibile risolvere tramite l'iniezione.

Suggerimento: il CommonServiceLocator (e l'adattatore Ninject per esso) sono stati appositamente progettati per questa situazione (librerie con dipendenze). Si codifica su CommonServiceLocator e quindi l'applicazione specifica quale DI / IoC esegue effettivamente il backup dell'interfaccia.

È un po 'doloroso il fatto che ora devi avere Ninject e CommonServiceLocator nella tua app, ma CommonServiceLocator è abbastanza leggero. Il tuo codice SDK / libreria solo usa CommonServiceLocator che è abbastanza pulito.

Altri suggerimenti

Suppongo che non ne abbia nemmeno bisogno. IoC è per cose pubbliche. Vai dritto per gli interni.

Ma - questa è solo la mia intuizione ...

Crea un'API interna secondaria che è diversa dall'API esterna. Potrebbe essere necessario eseguire la divisione manualmente ...

Voterò per la soluzione InternalsVisibleTo. Totalmente non un odore, davvero. Il punto dell'attributo è quello di abilitare il tipo di comportamento che desideri, quindi piuttosto che saltare tutti i tipi di cerchi elaborati per far funzionare le cose senza di esso, basta usare la funzionalità fornita dal framework per risolvere questo particolare problema.

Vorrei anche suggerire, se si desidera nascondere all'utente la scelta del contenitore, utilizzando ILMerge per combinare gli assiemi Ninject con l'assemblaggio SDK e applicare l'argomento / internalize per modificare la visibilità degli assiemi Ninject interno, quindi gli spazi dei nomi di Ninject non fuoriescono dalla tua libreria (mi dispiace, non sono riuscito a trovare un collegamento ai documenti ILMerge online, ma c'è un file doc nel download). C'è anche questo bel post sul blog sull'integrazione di ILMerge nel tuo processo di creazione.

Puoi

  • modifica Ninject
  • scegli un altro contenitore
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top