2014-02-13 31 views
1

我使用MVP模式创建经由工厂装载到外壳视图模块:保持演示参考活着但无视图给出参考它控制

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 Event Aggregator触发事件来填充模块。然而,我发现它永远不会生存。我的结论是,主持人(负责处理该事件)正在收集垃圾,因此公布的活动充耳不闻。我通过创建一个析构函数并对其进行了简化来确认这一点。

我可以找出可能的解决方案,但他们提出的警告:

1)我想设置KeepSubscriberReferenceAlive为真,但another SO answer states this should be a rare occurrence的。

2)我可以给view参考其presenter,但我认为view应该是完全愚蠢的,并且没有提及演示者。

3)我可以给ViewModuleFactory一个字段引用Presenter。工厂在该计划的生命中保持活力,因此主讲人的参考资料得以保留,但我认为这可能会完全打开另一个蠕虫。

什么是真正奇怪的是,我在加载完全相同的方式ViewFactory另一个模块,但不知何故,该演示是没有得到最终确定这样的一个。

任何帮助,将不胜感激。

回答

0

我在使用模型 - 视图 - 演示者模式时遇到过类似的问题,在我看来,选项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; } 
    } 
} 

虽然你的视图类现在要演示的参考,他们不知道实际主持人的具体类型,只要该字段是私有的,子类实际上不能以任何方式检索和使用主讲者,所以这仅仅成为您的框架的实现细节,用于将主持人的生命周期与其生命周期关联视图。