2012-02-07 10 views
8

In passato, ho usato le rondelle di turni che è un controller IoC di actionscript 3. Fondamentalmente la prima versione di switfsuspender aveva qualcosa di simile al kernel di Ninject chiamato iniettore.Ho bisogno di più Esempi pratici di Ninject

Se volevo creare un iniettore di applicazioni (con diciamo i mapping più rilevanti da utilizzare in tutta l'applicazione), ho dovuto iniettare l'iniettore stesso nelle classi dell'applicazione.

Mi chiedo ora qual è la pratica da utilizzare kernel.get <> tra diverse classi nell'applicazione. Dovrei iniettare il kernel stesso?

Personalmente preferisco usare kernel.inject ma se posso fare kernel.inject posso davvero iniettare le dipendenze manualmente, che è probabilmente migliore (bacio).

I casi di test sono buoni, ma sono lontani dai veri problemi pratici, quindi spero che tu possa aiutarmi a chiarire questo punto. Grazie.

Modifica: ho notato che alcune persone parlano di "root container", sembra che sia il concetto che sto cercando. Come dovrei configurare un container root e lasciare che le altre classi applicative lo sappiano?

codice di esempio Edit2 (ti prego di perdonare gli errori, è solo per esempio sake):

class SomeClass 
{ 
    public SomeClass() 
    { 
     Command cmd = new Command(); 

     cmd.execute(); 
    } 

} 

class SomeOtherClass:ISomeOtherClass 
{ 
public void allright() 
{ 
    //right 
} 
} 

class Command 
{ 
    ISomeOtherClass dependency; 

    void execute() 
    { 
    dependency.allright(); 
    } 

} 


Program.Main() 
{ 
    IKernel kernel = new StandardKernel(); 

    kernel.Bind<SomeClass>().ToSelf().InSingletonScope(); 
    kernel.Bind<ISomeOtherClass>().To<SomeOtherClass>(); 

    SomeClass sc = kernel.Get<SomeClass>(); 
} 

non ho ancora verificare ciò, perché sto ancora combattendo con alcuni problemi di inizializzazione, ma la mia domanda è, come la classe di comando può conoscere SomeOtherClass? La mia ipotesi attuale è di iniettare il kernel in SomeClass e utilizzare il metodo Inject.

risposta

11

Guardando al tuo esempio, è chiaro che SomeClass non è stato creato pensando a Inversion of Control; la soffiata è che ha una dipendenza da Command, ma il controllo di tale dipendenza è mantenuto all'interno di SomeClass stesso. (Command cmd = new Command();)

Per invertito il controllo di quella dipendenza, si avrebbe bisogno di avere un modo per iniettare la dipendenza che in SomeClass. Come Remo Gloor has indicated, il modo standard per farlo con Ninject è attraverso il costruttore.

Per fare ciò, si potrebbe cambiare SomeClass a qualcosa di simile:

class SomeClass 
{ 
    private ICommand _command; 

    public SomeClass(ICommand injectedCommand) 
    { 
     _command = injectedCommand; 
     _command.execute(); 
    } 

} 

Allo stesso modo si avrebbe bisogno il vostro comando per pubblicizzare la sua dipendenza:

class Command 
{ 
    private ISomeOtherClass _dependency; 

    public Command(ISomeOtherClass injectedSomeOtherClass) 
    { 
     _dependency = injectedSomeOtherClass; 
    { 

    void execute() 
    { 
     _dependency.allright(); 
    } 
} 

allora si sarebbe registrarsi vincolante il vostro comando in il kernel, forse come:

Program.Main() 
{ 
    IKernel kernel = new StandardKernel(); 

    kernel.Bind<SomeClass>().ToSelf().InSingletonScope(); 
    kernel.Bind<ICommand>().To<Command>(); 
    kernel.Bind<ISomeOtherClass>().To<SomeOtherClass>(); 

    SomeClass sc = kernel.Get<SomeClass>(); 
} 

il kernel sarebbe quindi in grado di camminare t la catena delle dipendenze e le inietta tutte.

+0

Grazie per la risposta ha senso, ma mentre è corretto, afferma solo che tutte le dipendenze devono essere conosciute in anticipo. Cosa succede quando questo non è possibile? (naturalmente quello che dico ha senso solo se gli oggetti vengono creati dinamicamente e ciò potrebbe accadere) – sebas

+0

diciamo che SomeClass deve creare un numero definitivo di oggetti dinamici. Like SomeClass diventa Level e deve creare 30 stelle. le stelle hanno alcune dipendenze, come può Level iniettare quelle dipendenze alle stelle usando il kernel? – sebas

+0

Questa è una buona domanda, e ti stai spostando oltre le semplici domande di iniezione di dipendenza a cui è possibile rispondere in questo formato. Questo tipo di situazione (creazione di oggetti complessi) tende a richiedere un altro pezzo, motivo per cui Remo ha menzionato le fabbriche nella sua risposta. Dovresti investigare o creare una fabbrica di stelle e iniettarla in SomeClass, oppure far risolvere a Ninject le stelle usando un metodo factory o Bind(). ToProvider(). –

5

Utilizzare l'iniezione del costruttore laddove possibile e Factories ogni volta che esiste una buona ragione per non creare le istanze insieme all'oggetto che dipende da esse.

kernel.Inject deve essere utilizzato solo quando non si sta modificando la creazione dell'oggetto. Per esempio. un WebForm

kernel.Get deve essere utilizzato esattamente una volta nella radice di composizione (ad esempio Program.Main o MVC3.DependencyResolver) per creare l'applicazione.

+2

Ciao Remo! Grazie per la risposta. Hai fornito informazioni utili, ma non è quello che volevo sapere. Mi stai dicendo che Get non dovrebbe essere usato come localizzatore di servizi, ma quello che ho chiesto era più questo: diciamo che ho una classe che ha bisogno di creare un comando in uno dei suoi metodi. Diciamo che il comando ha bisogno di alcune dipendenze iniettate e il kernel è stato definito al di fuori della classe che crea il comando. Come dovrei usare il kernel per iniettare le dipendenze all'interno di questo comando? Dovrei prima iniettare il kernel nella classe che crea il comando? – sebas

+0

il mio problema è qualcosa di simile a questo http://stackoverflow.com/questions/2862698/ninject-shared-di-ioc-taintainer ma non vorrei usare alcuna classe statica, preferisco iniettare il kernel a questo punto. – sebas

+0

Dovresti aggiungere un esempio di codice alla tua domanda su cosa vuoi fare. Tutto il resto sta solo supponendo. Normalmente le dipendenze dovrebbero essere passate usando l'iniezione del costruttore che viene eseguita automaticamente da Ninject. –