2010-12-09 58 views
0

在微軟看來注入樣品/條,他們有一個像下面的代碼:棱鏡查看注射演示和垃圾收集

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

這裏演示解決它包含類型IEmployeesView的公共財產,用於將視圖注入區域。解析演示者的好處是它會自動綁定到視圖(通過在構造函數中(通過統一))。但是,您不認爲Presenter容易發生垃圾回收,因爲在initialize方法的作用域結束之後沒有提及展示器的引用。

View/ViewModel顯然不會引用演示者,除非VM/View具有由演示者訂閱的事件。我們可以進入一個不一致的狀態,在該狀態下,視圖是活動的,但演示者是垃圾收集的。

爲了防止演示者垃圾回收,我們可能需要ViewModel中的KeepAlive屬性,該屬性只保留對演示者的引用,以防止其GC,但對我來說這聽起來很詭異。你在這種情況下做什麼或將做什麼?

請注意,在存在多個視圖實例的情況下,使用ContainerControlledLifetimeManager註冊演示者是不可行的。另外,如果演示者(帶有視圖)的通信模式是通過命令並且命令碰巧是棱鏡的DelegateCommands,那麼他們將只保留對演示者的弱引用,從而不會達到目的。

+0

容器*沒有提及演示者,那是你使用它的原因嗎?顯示的代碼只是獲取對該演示者的引用,並將其視圖粘貼到一個區域中...... – 2010-12-09 21:10:26

+0

您指的是一個容器? – 2010-12-09 21:42:07

回答

2

這是一個關於生命的複雜問題。在這個例子中,棱鏡文檔中的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); 
     } 

這關係的EmployeesPresenter的壽命到IEmployeesListPresenter的壽命。它是這樣的容器註冊:

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

非靜態或ContainerControlledLifetime,要麼。現在我們來看一下EmployeesListPresenter的實現。這裏是構造:

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(); 
     } 

現在我們看到EmployeesListPresenter在IEmployeesListView的一生綁起來。

因此,EmployeesPresenter的生命週期與EmployeesListView的生命週期相同,它基本上與控制樹中的一樣長。

這是一個很混亂的例子。你會發現棱鏡4樣本更直截了當......如果你有選擇的話,我會建議看看它們,並可能升級到棱鏡4。