Prism View 注入呈现器和垃圾收集

发布于 2024-10-07 01:39:09 字数 1034 浏览 2 评论 0原文

在 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 订阅的事件。我们可能会进入不一致的状态,其中视图处于活动状态,但演示者被垃圾收集。

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

请注意,在存在多个视图实例的情况下,向 ContainerControlledLifetimeManager 注册演示者是不可行的。此外,如果演示者(带视图)的通信模式是通过命令,并且命令恰好是 prism 的 DelegateCommands,那么它们只会保留对演示者的弱引用,因此也无法达到目的。

In Microsoft's view injection sample/article they have the code like the following:

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

here Presenter is resolved which contains the public property of type IEmployeesView and thats used for injecting the view to the region. The benefit of resolving the presenter is that it gets automatically tied to the view (by taking it in constructor (via unity)). However don't you think the Presenter is prone to garbage collection because nothing has reference to presenter after the scope of initialize method ends?

View/ViewModel obviously won't have reference to presenter unless VM/View has an event which is subscribed by presenter. We can go into an inconsistent state in which the view is active but the presenter is garbage collected.

To prevent garbage collection of presenter probably we'll need a KeepAlive property in ViewModel that just holds the reference to presenter for preventing its GC but that sounds hacky to me. What do you do or would do in this situation?

Please note that in a situation where there will be multiple instances of the view, registering the presenter with ContainerControlledLifetimeManager is not feasible. Also if the mode of communication for presenter (with view) is via commands and the commands happen to be DelegateCommands of prism then they will only keep weak reference to the presenter so that won't serve the purpose either.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

何其悲哀 2024-10-14 01:39:09

这是一个关于生命的复杂问题。在 Prism 文档的此示例中, EmployeesPresenter 的实现连接到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。

This is a complicated question about lifetime. In this example in the Prism documentation, the implementation of the 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);
        }

This ties the lifetime of the EmployeesPresenter to the lifetime of the IEmployeesListPresenter. It is registered with the container like this:

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

Not staticly or ContainerControlledLifetime, either. Now we have to look at the implementation of EmployeesListPresenter. Here is its constructor:

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

Now we see that the EmployeesListPresenter is tied up in the lifetime of the IEmployeesListView.

So, the lifetime of the EmployeesPresenter is the same as the EmployeesListView, which will be essentially as long as it is in the control tree.

This is a pretty confusing sample. You will find that the Prism 4 samples are much more straightforward... I would recommend looking at them and possibly upgrading to Prism 4 if you have a choice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文