5

Response.Redirect在坚持正确的层分离的同时,在 Model-View-Presenter 模式中调用 a 的最佳方法是什么?

4

4 回答 4

6

Succeeded我处理此问题的一种方法是让演示者引发视图将订阅的事件(如或其他)。当 Presenter 完成它的处理时,它会引发事件,该事件将由 View 处理。在该处理程序中,视图将重定向到下一页。

这样,演示者不需要知道任何关于页面或 URL 或任何东西的信息。它只知道它何时完成了任务并通过引发事件让视图知道。如果演示者成功或失败,您可以引发不同的事件,以防您需要重定向到不同的地方。

于 2010-01-22T19:21:28.027 回答
4

从概念上讲,我不知道这是否是最正确的方法。但是我在上一个 MVP 应用程序中所做的是创建一个包装器HttpContext.Current,我将其称为 HttpRedirector。我还为测试目的创建了一个虚拟重定向器。两者都跟踪最后一个重定向的 url,以便我可以在单元测试中检查当我在控制器/演示器上调用方法时重定向实际上发生了。使用 IOC 容器,我可以IRedirector根据环境(生产/测试)切换实现。

于 2010-01-24T08:49:02.940 回答
1

一旦奠定了基础工作,我们的工作方式就会很好地工作。我敢肯定有几种方法可以给猫剥皮。(反正谁给猫剥皮。猫很可爱!)

首先,这仅适用于 ASP.Net 编译的 Web 项目,而不是网站。

每个页面都应该从一个自定义的抽象基类继承,它看起来像这样:

public abstract class PageBase : Page
{
  private static string _baseUrl = "/";

  public static string BaseUrl
  {
    get { return _baseUrl; }
    set { _baseUrl = value; }
  }

  protected static string BuildUrl(string basePath)
  {
    if( !string.IsNullOrEmpty(basePath) && basePath.StartsWith("~/"))
    {
      basePath = basePath.replace("~/", BaseUrl);
    }
    return basePath;
  }

  protected static string LoadView(string path)
  {
    Response.Redirect(path);
  }
}

每个页面还实现了一个特定于页面的接口。每个特定于页面的接口也继承自一个基本接口:

public interface IPageBase()
{
  void LoadView(string path);
}

然后是每个页面定义它自己的BaseUrl 版本的问题。您可能需要考虑查询字符串/路径加密/等。

最后,您的任何演示者(应该引用特定于页面的接口)都可以获取所需页面上的静态 BuildUrl() 以进行查看,然后使用返回的路径调用 LoadView()。

于 2010-01-15T20:05:47.377 回答
1

这取决于您的演示者的通用性。如果您的演示者完全与 UI 无关(可以在 WinForms 和 WebForms 之间重用),那么您将不得不抽象重定向操作。在 WebForms 中,重定向操作将通过 Response.Redirect 在视图中实现。在 WinForms 中,(我否认有很多使用 WinForms 的经验)我的猜测是它将由 SomeForm.Show 实现。

一个简单的、令人难以置信的选项是在视图的界面中包含一个 ShowViewX() 方法。您可以为视图可以逻辑重定向到的每个表单设置一个。或者,视图可以实现类似 Show(ConnectedViews) 的接口方法,其中 ConnectedViews 是一个枚举,其中包含每个视图的值,这些视图可以从特定视图“重定向”到。此枚举将存在于演示者级别。

上述方法特定于视图-呈现器对。您可以改为将其实现为系统范围的事物。逻辑与上面类似,在基本视图和演示器中实现。每个表单都有一个 ShowView__(),或者一个 Show(Views) 方法,其中 Views 是所有表单的枚举。

这是封装和干燥之间的折腾。

于 2010-01-15T20:06:59.793 回答