【发布时间】:2010-12-09 20:50:06
【问题描述】:
在微软的视图注入示例/文章中,他们有如下代码:
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容易被垃圾回收,因为在initialize方法的作用域结束后没有任何东西引用presenter吗?
View/ViewModel 显然不会引用 Presenter,除非 VM/View 有一个由 Presenter 订阅的事件。我们可能会进入不一致的状态,即视图处于活动状态但演示者已被垃圾回收。
为了防止 Presenter 的垃圾收集,我们可能需要 ViewModel 中的 KeepAlive 属性,它只保存对 Presenter 的引用以防止其 GC,但这对我来说听起来很奇怪。在这种情况下你会做什么或会做什么?
请注意,在存在多个视图实例的情况下,向 ContainerControlledLifetimeManager 注册演示者是不可行的。此外,如果演示者(有视图)的通信模式是通过命令,并且命令恰好是 prism 的 DelegateCommands,那么它们只会保持对演示者的弱引用,这样也不会达到目的。
【问题讨论】:
-
容器不是持有对 Presenter 的引用,这就是你使用它的原因吗?显示的代码只是获取对该 Presenter 的引用,并将其 View 粘贴到一个区域中......
-
你所说的容器是什么?
-
Container 是 UnityContainer。通常,Resolve 本身不会将对象添加到容器中,除非您将类型注册为 ContainerControlledLifetimeManager 或 PerInstanceLifetimeManager(您可以编写),这会将其添加到容器中。
-
有趣的是,如果没有任何东西引用 Presenter 并且视图没有公开事件,那么我可以看到 Presenter 做任何事情的唯一方法将是在内部有一个计时器可以在视图上设置数据,否则没有任何东西可以调用演示者执行任何操作。
-
视图可以有多个实例。容器控制的生命周期管理器在那里没有意义。与视图进行通信的方式是通过命令和 prism 中的 DelegateCommands 保持对订阅者的弱引用。