ASP.NET MVP模式

3
我正在尝试在我的应用程序中实现 Model-View-Presenter 设计模式。MVP 模式的一般概念对我来说是众所周知的,但是我更加困扰于如何使用嵌套用户控件来实现它。
我有几种可能可以实现的情况,但是在执行之前,我想听听您的意见。 由于这更像是一个“概念”问题,我认为没有必要发布任何代码。
所以场景如下: 有1个页面用于连接2个用户控件。其中一个用户控件包含一个子用户控件。在这种情况下,我该如何使用 MVP 模式?
1 Page
  1 UC
  1 UC
     1 SubUC

编辑:

所以我想知道的基本上是,如何在使用MVP模式的两个用户控件(父级和子级)之间进行交互。

我将在没有MVP的ASP.net中给您展示一个示例:http://pastie.org/5452134

现在使用MVP,我们是否仍然要在CodeBehind中注册此类事件?知道这个父级和子级用户控件都将使用MVP模式。或者presenter会被包括在这种交互中?

最终,我可以更改代码为:http://pastie.org/5452180

但是我想知道这是否可以,考虑到MVP模式...

还是我们更需要像这样的方法:http://pastie.org/5452174

以上所有示例都是在父视图的CodeBehind中编写的。其中一个正确吗?如果不是,如何使用更好的方法实现此目标

编辑2:我已经在https://github.com/frederikprijck/ASP.NET-MVP上添加了一个示例解决方案,我认为这应该就是我想要的...


我不太确定你的问题是什么?MVP模式和UserControls之间的确切关系是什么?在这里可以看到MVP模式的一个简短示例:http://www.codeproject.com/Articles/134692/Model-View-Presenter-Pattern-Implementation-in-ASP - VinayC
关于 MVP 模式,它可以像在页面中一样在用户控件中使用。你提供的链接甚至没有提到用户控件?所以我想要实现的是在我的用户控件中实现 MVP 模式。顺便说一下:我知道 MVP 是如何工作的,我不是在问如何设置它... 我正在寻求处理嵌套用户控件的最佳实践。 - Frederik Prijck
1个回答

5
我认为没有问题 - 用户控件只是一个视图。而且一个Presenter可以同时与多个视图进行交互。所以在这种情况下,您的Presenter可以引用4个视图(一个用于页面,两个用于用户控件和最后一个用于子用户控件)。
或者,您想要每个Presenter拥有单个视图,在这种情况下,您可以将用户控件视为父视图(页面)的子视图,因此父视图需要向上传递和向下传递为Presenter设计的视图交互。但是,我更喜欢前一种方法,即Presenter处理多个视图的交互。
请参见SO上有关如何进行连线的相关问题:https://softwareengineering.stackexchange.com/questions/60774/model-view-presenter-implementation-thoughts
最后,您可能希望查看MVVM模式,我相信它非常适合组合UI。与Presenter不同,您将拥有View Model来控制视图和模型之间的交互-但是,View Model不知道视图-而是视图观察(并更新)View Model以呈现自身。请参见此处的文章(View Model被称为Presentation Model):http://www.codeproject.com/Articles/23340/Presentation-Model-in-Action
编辑:
老实说,我不喜欢您的任何方法。我喜欢MVP实现,其中Presenter通过接口持有对View的引用(没有紧密耦合),而View进行连线,即创建Presenter实例并注入View引用。Presenter侦听View事件并调用View上的方法。View从不直接调用Presenter的方法。(MVP的其他变体是可能的-请参见我寻求的SO答案)。因此,我将解释我之前解释过的两种方法。
方法1:每个用户控件都是独立的视图。将有一个公共Presenter来处理多个视图。例如:
public class Presenter1
{
    IView1 _view1;
    IView2 _view2;

    public Presenter1(IView1 view1, IView2 view2)
    {
        _view1 = view1;
        _view2 = view2;

        _view1.OnSave += OnSave;
        _view1.OnSomeEvent += OnSomeEvent;
        _view2.OnFoo += OnFoo;
    }

    public void OnSave()
    {
        var data1 = _view1.GetData();
        var data2 = _view2.GetData();
        // update model
        ...
    }

    public void OnSomeEvent()
    {
       // inform view2 about it
       _view2.DoOnSomeEvent();
    }

    ...
}

public partial class MyPage : Page, IView1
{
   public void Page_Load(...)
   {
     //do wire up
     _presenter = new Presenter(this, usercontrol1);
   }
   ...
}

基本思想是视图不会交叉通信。如果用户控件需要向页面传递信息,则会引发一个事件,由Presenter捕获并通知页面。视图被动地处理UI。

方法2:

用户控件和页面进行交互。在这种情况下,页面将充当最终的视图,Presenter将持有对其的引用。控件的事件将由页面处理,必要时页面会冒泡事件。例如,

IView1 : IView2 { }

public class Presenter1
{
   IView1 _view1;

   public Presenter1(IView1 view1)
   {
       _view1 = view1;

       _view1.OnSave += OnSave;
       _view1.OnSomeEvent += OnSomeEvent;
       _view1.OnFoo += OnFoo;
   }
   ...
}

public partial class MyPage : Page, IView1
{
       public void Page_Load(...)
       {
         //do wire up
         _presenter = new Presenter(this);

         // handle user control events
         UserControl1.Foo += UserControl1_OnFoo();
         UserControl1.XyzEvent += UserControl1_XyzEvent();

       }
       ...

       private void UserControl1_OnFoo(...)
       {
          // bubble up to presenter
          OnFoo(..)
       }

       private void UserControl1_XyzEvent(...)
       {
          // private interaction (purely about some UI manipulation), 
          // will not be bubble up to presenter
          ...
       }
}

我知道MVVM的工作原理,但我在这里使用MVP。正如所说,我也知道MVP的工作原理,只是有点困惑如何将不同的用户控件连接起来。谢谢你的回答,但它并没有真正回答我正在寻找的内容。我不是在寻找如何设置MVP,而是如何使用MVP处理多个用户控件及其交互(子用户控件的事件等)。如果我每个用户控件使用1个视图/1个Presenter,那么我该如何处理子用户控件?我是否应该在父Presenter中初始化子控件的Presenter? - Frederik Prijck
然后最终,我如何从子级向父级进行通信...如果没有MVP,我会在CodeBehind文件中使用事件来完成这个过程。但是在使用MVP时是否仍然相同?我将修改我的帖子以使其更清晰。 - Frederik Prijck
你说:“说实话,我不喜欢你的任何方法。我喜欢MVP实现方式,其中Presenter通过接口持有对View的引用(没有紧密耦合)”,只是为了澄清一下...我正在使用一个接口,我只是没有粘贴出来,因为那不是问题的一部分。 - Frederik Prijck
我不喜欢你们两种方法,因为我希望我的两个视图能够分别运行...如果这两个视图不需要分别运行,我会选择你的第一个选项。但是,由于我希望视图1及其Presenter能够独立于视图2及其Presenter工作...所以我想我需要一个修改过的第一个示例... - Frederik Prijck
@FrederikPrijck,我猜你想要的是为每个用户控件拥有独立的Presenter。在这种情况下,这些Presenter的连接和控制交互必须被移到外部 - 页面类(或者甚至是独立的控制器类)会是更好的选择。另请参见https://dev59.com/xnRC5IYBdhLWcg3wCMnX - VinayC
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接