简体   繁体   English

ASP.NET MVP模式

[英]ASP.NET MVP Pattern

I'm trying to implement the Model-View-Presenter design pattern in my application. 我正在尝试在我的应用程序中实现Model-View-Presenter设计模式。 The general concept of the MVP pattern is known for me, but I'm more struggling with getting it done using nested usercontrols. MVP模式的一般概念对我来说是已知的,但我更难以使用嵌套的用户控件来完成它。

I've got a few possible scenarios I might be able to implement, but before doing so I'd like to hear your opinion. 我有一些可能的方案我可以实现,但在此之前,我想听听你的意见。

I think it does not matter to post any of my code, since its more a "concept" I'm trying to understand. 我认为发布我的任何代码并不重要,因为它更像是一个我试图理解的“概念”。

So the scenario is: 所以场景是:

1 page used to connect 2 user controls. 1页用于连接2个用户控件。 One of these usercontrols contains a child usercontrol. 其中一个用户控件包含一个子用户控件。 How do I work around with MVP pattern in this case? 在这种情况下,我如何解决MVP模式?

1 Page
  1 UC
  1 UC
     1 SubUC

Edit: 编辑:

So basicly what I want to know is how we can interact between two views (parent and child) using MVP in both usercontrols. 基本上我想知道的是我们如何在两个用户控件中使用MVP在两个视图(父级和子级)之间进行交互。

I'll show you an example in ASP.net WITHOUT MVP: http://pastie.org/5452134 我将在没有MVP的ASP.net中向您展示一个示例: http//pastie.org/5452134

Now with MVP, do we still register to this kind of event using the CodeBehind? 现在使用MVP,我们是否仍然使用CodeBehind注册此类事件? Knowing that this parent and child usercontrol would both be using the MVP pattern. 知道这个父和子用户控件都将使用MVP模式。 Or does the presenter get's included in this interaction? 或者演示者是否包含在此互动中?

Eventually I can change the code to: http://pastie.org/5452180 最终我可以将代码更改为: http//pastie.org/5452180

But I'm wondering whether this is OK, considering the MVP pattern... 但考虑到MVP模式,我想知道这是否合适......

Or do we more need an approach like this: http://pastie.org/5452174 或者我们更需要这样的方法: http//pastie.org/5452174

All the above examples are written in the CodeBehind of the parent view. 以上所有示例都是在父视图的CodeBehind中编写的。 Is one of this correct? 这是正确的吗? If not, how can we achieve this using a better approach 如果没有,我们如何使用更好的方法实现这一目标

Edit 2: I've added a solution with my example approach at: https://github.com/frederikprijck/ASP.NET-MVP I think this should be pretty much what I wanted... 编辑2:我已经在我的示例方法中添加了一个解决方案: https//github.com/frederikprijck/ASP.NET-MVP我认为这应该是我想要的...

I don't see a problem - user control is nothing but a view. 我没有看到问题 - 用户控制只是一个视图。 And a presenter can interact with multiple views at a time. 演示者可以一次与多个视图进行交互。 So in this case, your presenter can have reference of say 4 views (one for page, two for user controls and last one for sub-user control). 因此,在这种情况下,您的演示者可以引用4个视图(一个用于页面,两个用于用户控件,最后一个用于子用户控件)。

Alternatively, you want to have single view per presenter and in such case, you can see user control as child view of the parent view(page) and so parent view need to bubble up and down view interactions meant for presenter. 或者,您希望每个演示者具有单个视图,在这种情况下,您可以将用户控件视为父视图(页面)的子视图,因此父视图需要为演示者提供向上和向下视图交互。 However, I would prefer the earlier approach where presenter handling interaction multiple views. 但是,我更喜欢早期的方法,其中演示者处理交互多个视图。

See this related question on SO on how wiring is done: https://softwareengineering.stackexchange.com/questions/60774/model-view-presenter-implementation-thoughts 请参阅有关如何完成接线的相关问题: https//softwareengineering.stackexchange.com/questions/60774/model-view-presenter-implementation-thoughts

Finally, you may want to look at MVVM pattern which I believe works great for compositional UI. 最后,你可能想看看MVVM模式,我相信它对于组合UI很有用。 Instead of presenter, you will have view model that will control the interaction between view and model - however, unlike presenter, view model does not know about view - rather view observes (and updates) view model to render itself. 您将拥有控制视图和模型之间交互的视图模型,而不是演示者 - 但是,与演示者不同,视图模型不了解视图 - 而是视图观察(和更新)视图模型以呈现自身。 See this article here (View Model is referred as Presentation Model): http://www.codeproject.com/Articles/23340/Presentation-Model-in-Action 在这里查看这篇文章(View Model被称为Presentation Model): http//www.codeproject.com/Articles/23340/Presentation-Model-in-Action

EDIT : 编辑

To be honest, I don't prefer any of your approaches. 说实话,我不喜欢你的任何方法。 I like MVP implementation where presenter holds reference to view via interface (no tight coupling) and view does the wiring ie creates presenter instance and inject the view references. 我喜欢MVP实现,其中presenter通过接口保持对视图的引用(没有紧耦合),并且视图执行连接,即创建presenter实例并注入视图引用。 The presenter listens to view events and call methods on view. 演示者侦听视图中的事件和调用方法。 View never calls directly on presenter's methods. View永远不会直接调用presenter的方法。 (Other variations of MVP are possible - see the SO answer that I had sought). (MVP的其他变体是可能的 - 参见我所寻求的SO答案)。 With this, I will explain two approaches that I had explained earlier. 有了这个,我将解释我之前解释过的两种方法。

Approach 1 : 方法1

Each user control is an independent view. 每个用户控件都是一个独立的视图。 There will be common presenter that will handle multiple views. 会有一个共同的演示者来处理多个视图。 For example, 例如,

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

Basic idea is that view does not do cross talk. 基本的想法是视图不做交叉谈话。 If user control needs to inform page some thing, it would raise an event that is caught by presenter and it informs page about it. 如果用户控件需要通知页面某些内容,则会引发由演示者捕获的事件,并将其通知页面。 Views are passive and handles UI. 视图是被动的并处理UI。

Approach 2: 方法2:

Usercontrol and Page interacts. Usercontrol和Page交互。 In such case, Page will act as a ultimate view and Presenter will hold reference to it. 在这种情况下,Page将作为终极视图,Presenter将参考它。 Control's events will be handled by page and page will bubble up the event if necessary. 控件的事件将由页面处理,页面将在必要时冒泡事件。 For example, 例如,

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
          ...
       }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM