2012-12-06 10 views
6

Mi chiedo come gestire un oggetto utilizzando DI. Supponiamo che io sono una classeGestione classi usa e getta Dipendenza iniezione

class Foo : IFoo, IDisposable 
{ 
    // ... 
} 

Poi questa classe viene iniettato in un'altra classe

class Bar 
{ 
    public Bar(IFoo foo) 
    { 
     this.Foo = foo 
    } 

    IFoo Foo { get; set; } 
} 

Poi mi legano questo in un certo ambito (il mio esempio utilizza MVC e Ninject)

this.Bind<IFoo>().To<Foo>().InRequestScope(); 

I Mi chiedo, dal momento che il framework Dipendenza Injection gestisce il ciclo di vita di Foo, dovrei implementare IDispoable in Bar? Il mio pensiero è che DI stia gestendo il ciclo di vita di Foo, quindi non toccarlo, nel caso in cui un'altra classe stia usando Foo. Inoltre, dal momento che l'oggetto usa e getta viene passato in Bar come parametro del costruttore, Bar non involucro un oggetto usa e getta, in modo che non si sa come il chiamante di Bar vuole usare Foo dopo Bar è garbage collection. È giusto?

+1

Nicholas Blumhardt ha un ottimo post su questo argomento, utilizzando come esempio Automatico, ma applicabile in generale http://nblumhardt.com/2011/01/an-autofac-lifetime-primer/ – fsimonazzi

+0

Guardando alcuni articoli MSDN, Microsoft farà entrambe le cose: http://msdn.microsoft.com/en-us/library/yhfzs7at%28v=vs.110%29 (StremReader) "L'oggetto StreamReader chiama Dispose() sull'oggetto Stream fornito quando StreamReader .Dispose si chiama " ma http://msdn.microsoft.com/en-us/library/z7ha67kw%28v=vs.110%29 (Bitmap)" È necessario mantenere il flusso aperto per tutta la durata della Bitmap. " – Michael

risposta

3

Sì, le vostre ipotesi sono corrette. Ninject disporrà l'oggetto per te.

+0

L'ho capito durante i test. Credo che la mia domanda principale sia, chi è responsabile per lo smaltimento di un oggetto. La mia conclusione basata sulla ricerca era che l'oggetto che ha creato l'oggetto usa e getta è responsabile della sua eliminazione. Quindi, in questo caso, Ninject. – Michael

3

Questo è il problema generale della gestione della durata. La regola di base è che chi crea un oggetto ha la proprietà di quell'istanza. Il proprietario dovrebbe disporre/distruggere quell'istanza. La proprietà può essere passata a qualcun altro, il che rende responsabile di "qualcun altro" distruggere quell'istanza.

Nel tuo caso l'istanza di Foo non viene creata da Bar, quindi bar non è responsabile di smaltire quell'istanza. Poiché Ninject ha creato quell'istanza per te, è responsabile della sua pulizia.

La proprietà può essere passata, ma questo deve essere qualcosa di esplicito. Un buon esempio di esplicita passaggio di proprietà è il modello di progettazione di fabbrica:

IFoo CreateNewFoo(); 

Anche se questo metodo crea nuove IFoo casi, è abbastanza chiaro che si passa la proprietà al chiamante.

Un buon esempio di modo BAD di passare la proprietà è la classe .NET StreamReader. Prende un oggetto usa e getta nel suo costruttore, ma ne assume la proprietà. Anche se la documentazione afferma che la classe dispone l'oggetto dato, questo comportamento abbaglia molti sviluppatori, perché va contro la regola generale di proprietà. Microsoft ha finalmente risolto questo problema in .NET 4.5 aggiungendo un sovraccarico di ctor che consente di sopprimere lo smaltimento del flusso specificato.