如何在没有视图引用演示者的情况下将演示者注入视图

时间:2012-01-27 21:35:37

标签: asp.net inversion-of-control mvp

在经典的Passive-MVP模式中,如何完全避免在我的视图中引用演示者?仍然注入需要视图实例作为参数的presenter实例。

以asp.net为例:

  • 我实现的视图(Web项目)不应该引用Presenters。 (既不是IPresenter也不是具体的)
  • 当视图实例化时(基本上是我的网页),应该使用当前视图的引用来实例化演示者。
  • 我使用unity作为我的ioc容器。

现在,我在网页背后的代码中所做的是:

public partial class SomePage : MyBasePage, ISomeView
{
    private readonly ISomePresenter presenter;

    public SomePage()
    {
        this.presenter = ResolveSomeWay(this);
    }
}

为此,我在视图实现中引用了“Presenter Contracts DLL”。有没有办法完全避免这个参考&当视图实例化时,仍然将视图实例与演示者挂钩?

我只关心演示者实例化,因为演示者的构造函数可以将传递的参数视图实例设置为其View Property&它订阅视图的事件,用于任何未来的通信。

感谢大家的时间。

1 个答案:

答案 0 :(得分:0)

您可以“发布”新的View实例化到消息总线,Presenter工厂可以将实例化的View“绑定”到Presenter。虽然视图与演示者无关,但它不会是消息总线。

public partial class SomePage : MyBasePage, ISomeView
{
    // Alternative #1
    public SomePage(IMessageBus messageBus)
    {
        // You publish a message saying that a handler for ISomeView is to handle the
        // message.
        messageBus.Publish<ISomeView>(this);
    }
    // Alternative #2
    public SomePage()
    {
        Resolver.Resolve<IMessageBus>().Publish<ISomeView>(this);
    }
}

// This could be somewhere else in your application (this could be a separate DLL), but 
// I will use the Global.asax.cs here, for simplicity
public void Application_Start()
{
    Container.Resolve<IMessageBus>()
             .Subscribe<ISomeView>(someView => 
                 {
                    var presenter = new SomePresenter(someView);
                 });
}

public interface ISomeView {
    event Action<ISomeView> SomeEvent;
}

public class SomePresenter
{
    public SomePresenter(ISomeView view) {
        // if you attach the presenter to the View event, 
        // the Garbage Collector won't finalize the Presenter until
        // the View is finalized too
        view.SomeEvent += SomeEventHandler;
    }

    private void SomeEventHandler(ISomeView view) { 
       // handle the event
    }
}