【问题标题】:Keeping a presenter reference alive without giving a reference to the view it controls保持演示者引用活动而不提供对其控制的视图的引用
【发布时间】:2014-02-13 19:15:55
【问题描述】:

我正在使用 MVP 模式创建通过工厂加载到 Shell 中的视图模块:

public class ViewModuleFactory : IViewModuleFactory
{
  private readonly IEventAggregator Events;

  public ViewModuleFactory(IEventAggregator Events)
  {
    this.Events = Events;
  }

  public Control CreateModule()
  {
    var view = new View();
    var presenter = new Presenter(Events, view);

    return view;
  }
}

模块加载到 shell 后,我通过 Prism 事件聚合器触发一个事件来填充模块。然而,我发现它永远不会填充。我的结论是演示者(处理事件)正在收集垃圾,因此发布的事件被置若罔闻。我已经通过创建析构函数并对其进行断点来确认这一点。

我可以确定可能的解决方案,但它们带有警告:

1) 我想将KeepSubscriberReferenceAlive 设置为true,但是another SO answer states this should be a rare occurrence

2) 我可以为 view 提供对其 presenter 的引用,但我的阵营认为 view 应该是完全愚蠢的,并且与演示者无关。

3) 我可以为ViewModuleFactory 提供对Presenter 的字段引用。工厂在程序的生命周期内一直存在,因此演示者参考被保留,但我觉得这可能会完全打开另一罐蠕虫。

真正奇怪的是,我在 ViewFactory 中有另一个模块,它的加载方式完全相同,但不知何故,演示者并没有像现在这样完成。

任何帮助将不胜感激。

【问题讨论】:

    标签: c# winforms events garbage-collection mvp


    【解决方案1】:

    我在使用 model-view-presenter 模式时遇到过类似的问题,我认为选项 2 是最简单的方法。

    通过让所有视图实现以下基本接口,您可以在视图不“了解”具体演示者的情况下执行此操作:

    public interface IView
    {
        object Presenter { set; }
    }
    

    当您使用 WinForms 时,您可以拥有一个实现IView 接口并将演示者对象存储在Tag 属性中的基类。

    public abstract class ViewBase : UserControl, IView
    {
        public object Presenter
        {
            set { this.Tag = value; }
        }
    }
    

    然后可以更新您的演示者基类以设置 IView.Presenter 属性并将自身传递给视图以确保引用保持活动状态,例如

    public class Presenter
    {
        public Presenter(View view)
        {
            view.Presenter = this;
        }
    }
    

    或者,您的视图类可以直接持有对演示者对象的引用,如下所示:

    public abstract class ViewBase : UserControl, IView
    {
        private object _presenter;
    
        public object Presenter
        {
            set { this._presenter = value; }
        }
    }
    

    虽然您的视图类现在有一个对演示者的引用,但它们不知道演示者的实际具体类型,并且只要该字段是私有的,子类实际上就不能以任何方式检索和使用演示者,所以这只是变成框架的实现细节,用于将演示者的生命周期与其关联视图的生命周期联系起来。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-23
      • 1970-01-01
      • 2013-02-08
      • 2011-06-09
      相关资源
      最近更新 更多