【问题标题】:Decoupling the view, presentation and ASP.NET Web Forms解耦视图、表示和 ASP.NET Web 窗体
【发布时间】:2010-04-05 14:03:37
【问题描述】:

我有一个 ASP.NET Web 窗体页面,演示者需要用控件填充该页面。这种交互对页面生命周期有些敏感,我想知道是否有一个我不知道的技巧。

我想对整个事情采取实际行动,但不影响可测试性。

目前我有这个:

public interface ISomeContract
{
    void InstantiateIn(System.Web.UI.Control container); 
}

此合同依赖于 System.Web.UI.Control,我需要它才能使用 ASP.NET Web 窗体编程模型进行操作。但无论是视图还是演示者都可能不了解 ASP.NET 服务器控件。

我该如何解决这个问题?如何在我的具体视图中使用 ASP.NET Web 窗体编程模型而不在我的合同程序集中使用 System.Web.UI.Control 依赖项?

为了澄清一点,这种类型的界面都是关于 UI 组合的(使用 MEF)。它在整个框架中都是已知的,但实际上只能从具体视图中调用。具体视图仍然是唯一了解 ASP.NET Web 窗体的内容。然而,那些说InstantiateIn(System.Web.UI.Control) 的公共方法存在于我的合同程序集中,这意味着对 ASP.NET Web 窗体的依赖。

我一直在考虑一些双重调度机制甚至访问者模式来尝试解决这个问题,但我还不知道我想朝哪个方向发展,我真的想就此事提供一些意见。

【问题讨论】:

  • 为什么视图和演示者无法了解 ASP.NET 服务器控件?
  • @Kirk 可测试性?嘲笑这些东西会不会很困难(几乎不可能)?

标签: c# asp.net dependency-injection mvp mef


【解决方案1】:

不确定访客将如何解决问题。但是为什么不让你的合同看起来像这样:

public interface ISomeContract
{
    void InstantiateIn(IControl container); 
}

使用 IControl 实现,可能在另一个程序集中以保持您的合同程序集干净,它包裹在 ASP.NET System.Web.Control 上,例如:

public class AspnetControl : IControl
{
    public AspnetControl(System.Web.Control control) { }

    // IControl members that dispatch to control
}

尽管最终 IControl 很有可能最终看起来非常像 System.Web.Control(因此一开始就失去了抽象它的意义),但它仍然是非常可测试的,并且您的观点并且演示者不必了解 ASP.NET。

【讨论】:

  • 你的 IControl 接口可以暴露你的控制器可以监听的某些“生命周期”事件——大多数时候你最终只是包装了 Web 表单事件(也许一个小助手类可以减轻这种痛苦?)但是,如果您希望自己的观点完全愚蠢,那么您需要忍受它。
【解决方案2】:

您可以将合同与 Web 控件分离的一种方法是使用单独的编写器来处理从 ISomeContract 获取信息并将其放置在您的 Control 容器中。这可以驻留在引用合同程序集和 System.Web 的程序集中。

【讨论】:

  • 你能举个具体的例子吗?
【解决方案3】:

我一直在阅读有关敏捷技术、tdd、单元测试、solid、设计模式的文章,但我感到完全无力弥合从所有这些美妙的理论到 asp.net 网络表单的鸿沟。

今天早些时候,我再次尝试找到解决此问题的方法,并找到了这篇文章:

这是一本我认为可以解决我所有问题的书的摘录,但本章实际上只是介绍了在 Web 表单中实现 MVP 模式的可能性,最后说它并不实用。据我所知,本书的其余部分是关于测试 asp.net MVC。

还有一个旨在将爱带回网络表单平台的新项目:

【讨论】:

    【解决方案4】:

    在“正常”的 ASP.NET Web 表单中,您的页面/用户控件在技术上“负责”处理,并将其生命周期强加于代码。无论您喜欢与否,页面都是 Presenter 和 View。

    在这种环境中实现 MVP 模式的大多数尝试只是在已经过于复杂的环境中增加了过多的复杂性!假装另一个班级是 Presenter 只是……假装。 (在 MVC 网站中,Controller 确实控制了代码,而 View 没有,所以这个论点不再适用。)

    我的建议是让视图照顾自己的生命周期,并让它调用 Repositories 和 Model 类来检索/保存数据并调用命令。

    在这种方法中,模型类不需要了解有关 System.Web 的任何信息。这些相同的模型类可以在未来的 MVC 网站或 Silverlight 中使用,或作为 WPF 应用程序的 Web 服务,或嵌入 WPF 应用程序等。由视图决定如何实现(使用控件)它从模型中获得的响应/数据。

    如果您正确设置模型类以支持依赖注入,则可以随意测试模型类。

    希望有帮助!

    【讨论】:

      猜你喜欢
      • 2015-12-21
      • 2011-07-29
      • 1970-01-01
      • 2011-09-03
      • 2018-09-15
      • 2011-08-25
      • 1970-01-01
      • 1970-01-01
      • 2016-11-12
      相关资源
      最近更新 更多