2010-12-09 9 views
0

In Microsofts Ansicht Injektion Probe/article sie haben den Code wie folgt aus:Prism Ansicht Injection Presenter und Garbage Collection

public void Initialize() 
{ 
    this.RegisterViewsAndServices(); 
    EmployeesPresenter presenter = this.container.Resolve<EmployeesPresenter>(); 
    IRegion mainRegion = this.regionManager.Regions[RegionNames.MainRegion]; 
    mainRegion.Add(presenter.View); 
} 

http://msdn.microsoft.com/en-us/library/dd458920.aspx

hier Presenter wird aufgelöst, welche die öffentliche Eigenschaft des Typs IEmployeesView enthält und das wird verwendet, um die Ansicht in die Region zu injizieren. Der Vorteil des Auflösens des Präsentators besteht darin, dass er automatisch an die Ansicht gebunden wird (indem er im Konstruktor genommen wird (über die Einheit)). Aber denkst du nicht, dass der Presenter anfällig für die Garbage Collection ist, weil sich nach dem Ende der Initialisierungsmethode nichts auf den Presenter bezieht?

View/ViewModel hat offensichtlich keinen Bezug zum Moderator, es sei denn, VM/View hat ein Ereignis, das vom Moderator abonniert wurde. Wir können in einen inkonsistenten Zustand wechseln, in dem die Ansicht aktiv ist, der Moderator jedoch als Müll gesammelt wird.

Um Speicherbereinigung von Presenter zu verhindern, benötigen wir wahrscheinlich eine KeepAlive-Eigenschaft in ViewModel, die nur den Verweis auf Presenter hält, um seinen GC zu verhindern, aber das klingt Hacky für mich. Was machst oder machst du in dieser Situation?

Bitte beachten Sie, dass in einer Situation, in der es mehrere Instanzen der Ansicht gibt, die Registrierung des Präsentators mit ContainerControlledLifetimeManager nicht möglich ist. Auch wenn der Kommunikationsmodus für den Moderator (mit der Ansicht) über Befehle erfolgt und die Befehle zufällig Delegiertenkommandos des Prismas sind, werden sie nur einen schwachen Bezug auf den Präsentator behalten, so dass dies auch nicht dem Zweck dient.

+0

Enthält * der Container * nicht den Verweis auf den Presenter, weshalb verwenden Sie ihn? Der Code zeigt nur einen Verweis auf diesen Presenter, und seine Ansicht in eine Region ... –

+0

Was meinen Sie als Container? –

+0

Container ist der UnityContainer. In der Regel fügt ein Resolve <> selbst das Objekt nicht zum Container hinzu, es sei denn, Sie registrieren den Typ als ContainerControlledLifetimeManager oder PerInstanceLifetimeManager (den Sie schreiben können), der es dem Container hinzufügt. – aqwert

Antwort

2

Dies ist eine komplizierte Frage über die Lebensdauer. In diesem Beispiel in der Prism-Dokumentation, die Umsetzung der EmployeesPresenter hooks up to an event on the EmployeesListPresenter:

public EmployeesPresenter(
      IEmployeesView view, 
      IEmployeesListPresenter listPresenter, 
      IEmployeesController employeeController) 
     { 
      this.View = view; 
      this.listPresenter = listPresenter; 
      this.listPresenter.EmployeeSelected += new EventHandler<DataEventArgs<BusinessEntities.Employee>>(this.OnEmployeeSelected); 
      this.employeeController = employeeController; 

      View.SetHeader(listPresenter.View); 
     } 

Dies bindet die Lebensdauer des EmployeesPresenter auf die Lebensdauer des IEmployeesListPresenter. Es ist mit dem Container wie folgt registriert:

this.container.RegisterType<IEmployeesListPresenter, EmployeesListPresenter>(); 

Nicht statisch oder ContainerControlledLifetime, entweder. Jetzt müssen wir uns die Implementierung von EmployeesListPresenter ansehen. Hier ist seine Konstruktor:

public EmployeesListPresenter(IEmployeesListView view, 
      IEmployeeService employeeService) 
     { 
      this.View = view; 
      this.View.EmployeeSelected += delegate(object sender, DataEventArgs<BusinessEntities.Employee> e) 
      { 
       EmployeeSelected(sender, e); 
      }; 
      view.Model = employeeService.RetrieveEmployees(); 
     } 

Jetzt sehen wir, dass die EmployeesListPresenter in der Lebensdauer des IEmployeesListView gebunden.

So ist die Lebensdauer des EmployeesPresenter die gleiche wie die EmployeesListView, die im Wesentlichen so lange wie in der Steuerelementstruktur ist.

Dies ist ein ziemlich verwirrendes Beispiel. Sie werden feststellen, dass die Prism 4-Beispiele viel einfacher sind ... Ich würde empfehlen, sie zu betrachten und möglicherweise auf Prism 4 zu aktualisieren, wenn Sie die Wahl haben.

+0

Das ist wahr, dass die Lebensdauer implizit in einer bestimmten Situation behandelt wird, weil der Moderator sich an ein Ereignis gebunden hat, das von der Ansicht veröffentlicht wurde, aber dies kann nicht konsistent als Muster in einer Anwendung verfolgt werden. Die wirkliche Frage ist, welche Life-Time-Management-Strategie jeder in einer solchen Situation nutzt? –

+1

@Hasan Khan: In meinem Fall verwende ich MVP nicht ... Ich denke, es macht die Dinge zu sehr kompliziert. Ich benutze MVVM und erlaube den ViewModels, direkt über den EventAggregator oder einen anderen Mechanismus zu kommunizieren. Ich denke nicht, dass das Einbringen einer dritten Partei viel mehr als Komplikation mit sich bringt. Ich denke, dass Sie diese Verschiebung auch in den Prism 4-Samples sehen werden. –

+0

@anderson ichmes - Wenn Sie eine Chance bekommen, bitte werfen Sie einen Blick auf meine Frage hier. http://stackoverflow.com/questions/15049256/wpf-prism-4-1-garbage-collection-memory-issues Ich benutze auch MVVM, aber kann nicht herausfinden, was ich habe ein Speicherleck in meiner sehr einfachen Prism-Demo-App. –