2012-12-06 33 views
6

Zastanawiam się, jak zarządzać obiektem przy użyciu DI. Załóżmy, że mam klasęZarządzanie klasami jednorazowymi Injection Injection

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

Potem ta klasa jest wstrzykiwany do innej klasy

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

    IFoo Foo { get; set; } 
} 

Następnie wiążę to w pewnym zakresie (mój przykład używa MVC i Ninject)

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

I zastanawiam się, skoro struktura Dependency Injection obsługuje cykl życia Foo, czy powinienem wdrożyć IDispoable w Bar? Uważam, że DI zarządza cyklem życia Foo, więc nie należy go dotykać, jeśli inna klasa używa Foo. Ponadto, ponieważ jednorazowy obiekt zostanie przekazany do Bar jako parametr konstruktora, Bar nie okład jednorazowy obiekt, więc nie wiem, jak rozmówca z Bar chce wykorzystać Foo po Bar jest śmieci zebrane. Czy to jest poprawne?

+1

Nicholas Blumhardt ma wielki post na ten temat, używając Autofact jako przykład, ale dotyczy w ogóle http://nblumhardt.com/2011/01/an-autofac-lifetime-primer/ – fsimonazzi

+0

Patrząc na niektórych artykułów MSDN, to wygląda na to, że Microsoft wykona obie: http://msdn.microsoft.com/en-us/library/yhfzs7at%28v=vs.110%29 (StremReader) "Obiekt StreamReader wywołuje Dispose() na dostarczonym obiekcie Stream, gdy StreamReader .Dispose jest nazywane " , ale http://msdn.microsoft.com/en-us/library/z7ha67kw%28v=vs.110%29 (Bitmapa)" Musisz zachować strumień otwarty przez cały czas trwania Bitmapy. " – Michael

Odpowiedz

3

Tak, twoje założenia są poprawne. Ninject udostępni ci obiekt.

+0

Zrozumiałem to podczas testów. Domyślam się, że moje główne pytanie brzmi: kto jest odpowiedzialny za pozbycie się przedmiotu. Mój wniosek oparty na wyszukiwaniu polegał na tym, że obiekt, który utworzył obiekt jednorazowy, jest odpowiedzialny za jego usunięcie. Tak więc w tym przypadku Ninject. – Michael

3

Jest to ogólny problem zarządzania czasem życia. Podstawową zasadą jest to, że ten, kto tworzy obiekt, jest właścicielem tej instancji. Właściciel powinien wyrzucić/zniszczyć to wystąpienie. Własność można przekazać komuś innemu, co powoduje, że "ktoś inny" jest odpowiedzialny za zniszczenie tej instancji.

W twoim przypadku instancja Foo nie jest tworzona przez pasek, więc pasek nie jest odpowiedzialny za usunięcie tej instancji. Ponieważ Ninject stworzył tę instancję dla ciebie, jest odpowiedzialny za jej oczyszczenie.

Własność można przekazać dalej, ale musi to być coś jawnego. Dobrym przykładem wyraźnego przejścia własności jest fabryczne wzornictwo:

IFoo CreateNewFoo(); 

Chociaż metoda ta stwarza nowe IFoo instancji, to jest dość oczywiste, że przechodzi on na własność z powrotem do osoby dzwoniącej.

Dobrym przykładem złego sposobu przekazywania praw własności jest klasa .NET o nazwie StreamReader. Zajmuje obiekt jednorazowy w swoim konstruktorze, ale bierze na siebie odpowiedzialność. Mimo że dokumentacja stwierdza, że ​​klasa udostępnia dany obiekt, to zachowanie oszałamia wielu programistów, ponieważ jest to sprzeczne z ogólną zasadą własności. Microsoft naprawił to ostatecznie w .NET 4.5, dodając przeciążenie ctor, które pozwala tłumić usuwanie danego strumienia.