Tempo di vita transitorio e iniezione del costruttore

2

Sto lavorando a un piccolo risolutore delle dipendenze leggero trovato qui

link

Attualmente se lo fai

var instance = container.Get<Foo>();

Ottieni una nuova istanza per ogni chiamata a Ottieni

Questo è corretto quando ci si trova in una gestione a vita transitoria. Ma qual è il comportamento previsto quando si utilizza l'iniezione del costruttore?

Diciamo che hai questa catena di dipendenze, con gli argomenti del costruttore

ClassOne (ClassTwo, ClassThree)

ClassTwo (ClassThree)

Ora facciamo un container.Get<ClassOne>() ; Dovrebbe essere ClassThree uguale per ClassOne e ClassTwo ?

modifica: la domanda è: secondo te, la maggior parte degli utenti si aspetta che il comportamento del tempo di vita transitorio si abbini all'iniezione del costruttore durante una chiamata a Get<T> .

modifica: Sia Ninject, Castle e Unity sembrano creare nuove istanze, quindi probabilmente questo è il modo in cui dovrebbe funzionare (e questo è il modo in cui funziona proprio ora)

modifica: hmmm. Interessante StructureMap in realtà riutilizza l'istanza, ecco l'output di un test che ho fatto (i numeri sono hashcode)

Ninject.StandardKernel 65778530 34340385

Microsoft.Practices.Unity.UnityContainer 9874138 2186493

Castle.MicroKernel.DefaultKernel 27253481 44856655

StructureMap.Container 14259084 14259084

Codice per testare sopra link

modifica: In realtà se non si specifica .LifestyleTransient() , il castello avrà lo stesso comportamento di StructureMap, il che significa che sarà la stessa istanza per Resolve

    
posta Anders 14.04.2015 - 09:16
fonte

1 risposta

2

La risposta ovvia, anche se odiosa, sarebbe ovviamente "dipende" ...;)

La maggior parte dei resolver nei contenitori "IoC" principali là fuori ti permettono di specificare questo quando definisci lo schema di risoluzione. In Castle Windsor, ad esempio, puoi definire la durata come Singleton, Transient, Bound, Thread, ... ( c'è un mucchio ). Il tuo esempio è un'istanza "Bound" abbastanza chiara, IF ClassThree è una classe di repository. (Altrimenti, ovviamente non è così chiaro.)

Per elaborare, la vera domanda è se, nel tuo esempio, le istanze ClassOne e ClassTwo abbiano effettivamente bisogno di accedere alla stessa istanza di ClassThree, o se in realtà devono avere istanze separate.

In definitiva, penso che questo dipenda dall'utilizzatore del risolutore poiché non esiste un modo reale per sapere se una classe arbitraria dovrebbe vivere o morire. Il mio suggerimento sarebbe quello di decidere su un'implementazione predefinita (sceglierei transitori) ma fornire supporto per modificare lo stile di vita di conseguenza.

    
risposta data 14.04.2015 - 10:43
fonte