Prism View Injection Presenter和垃圾收集

时间:2010-12-09 20:50:06

标签: wpf mvvm mvp prism

在Microsoft的视图注入示例/文章中,他们拥有如下代码:

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

此处Presenter已解析,其中包含IEmployeesView类型的公共属性以及用于将视图注入区域的公共属性。解析演示者的好处是它会自动绑定到视图(通过构造函数(通过统一))。但是你不认为Presenter容易进行垃圾收集,因为在初始化方法的范围结束后没有任何东西引用了presenter吗?

View / ViewModel显然不会引用presenter,除非VM / View有一个由演示者订阅的事件。我们可以进入一个不一致的状态,其中视图处于活动状态,但是演示者是垃圾收集的。

为了防止presenter的垃圾收集,我们可能需要ViewModel中的KeepAlive属性,该属性只保存对presenter的引用以防止其GC,但这对我来说听起来很糟糕。在这种情况下你做什么或者做什么?

请注意,在存在多个视图实例的情况下,使用ContainerControlledLifetimeManager注册演示者是不可行的。此外,如果演示者(带有视图)的通信模式是通过命令而命令恰好是棱镜的DelegateCommands,那么他们只会对演示者保持弱引用,这样也不会达到目的。

1 个答案:

答案 0 :(得分:2)

这是一个关于终生的复杂问题。在Prism文档的这个例子中,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相同,后者基本上与控制树中的一样长。

这是一个非常令人困惑的样本。您会发现Prism 4样本更简单......如果您有选择,我建议您查看它们并可能升级到Prism 4.

相关问题