在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,那么他们只会对演示者保持弱引用,这样也不会达到目的。
答案 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.