【问题标题】:i have a problem implementing the mvp pattern in c# and asp.net我在 c# 和 asp.net 中实现 mvp 模式时遇到问题
【发布时间】:2011-09-09 06:14:15
【问题描述】:

我已经创建了一个 MVP 模式的论坛系统,但我不确定我是否以正确的方式实现它。所以这就是我的结果:

  • 我创建了一个包含三个表的数据库:论坛、线程、帖子
  • 向项目中添加了一个新的类型化数据集,然后将所有表拖入其中
  • 创建了三个新类:ForumsModel、ThreadsModel、PostsModel
  • 新增三个接口:IForumView、IThreadView、IPostView
  • 另外三个类:ForumsPresenter、ThreadsPresenter、PostsPresenter

在模型类中,我只调用类型化的数据集方法,而在演示者中,我调用了模型方法。视图为.aspx 页。这就是论坛系统的全部内容,但这里是棘手的部分:

由于 MVP 模式是一种 UI 模式,我必须在应用程序本身中验证数据。所以在我的设计中,MVP 就是应用程序!

我做错了什么?

编辑 1: 首先是关于为什么我选择带有存储过程的类型化数据集而不是其他选项:它是最轻量级的数据提供程序,不会损害您拥有的任何架构.其他选项是直接 sql,这对于新创建的应用程序不是一个好的选择,LINQ to sql 类太重而无法用每个请求实例化,实体框架很棒,但对于这样一个简单的任务来说太多了!至少如果我正在创建一个博客引擎,那将是我的第一选择。 至于我为什么不选择 MVC,那是因为我认为 MVP 是更好的模式,因为它可以完全分离我的应用程序的不同部分。最后这是一个问题,但你应该能够实现任何模式,对吧? 我见过不同风格的 MVP,但我正在尝试实现的是:

model<------------->presenter<-------------->view

databind 选项适用于我所记得的由 martin fawler 引入的表示模型模式,但我正在尝试创建的是一个 microsoft 版本,它基本上是 PM 模式的扩展版本。

两天前我问了一个关于数据验证的问题,有人建议我应该在“应用程序本身”中进行,所以当我问这个“应用程序”在哪里时,他说 MVP 是一种 UI 模式,它不应该成为你的“应用程序”,你应该在你的用户界面层实现 MVP。所以这就是我首先问这个问题的原因!

【问题讨论】:

    标签: c# asp.net database mvp strongly-typed-dataset


    【解决方案1】:

    有了 MVP,后面的代码变成了基于 View 接口的 View 实现。

    View 接口包含 Presenter 需要绑定的页面事件以更改 View 的状态,以及它可能需要的属性和方法。例如,它可以挂钩 onLoad 事件并调用 View 以更改其状态。在这样做时,它与 View 实现无关,并且对控件一无所知。这意味着您可以在没有 ASPX 实例的情况下编写单元测试。

    要创建自动连接的 MVP 引擎,您将使用基本页面、泛型和 IoC。 IoC 允许您为 WebContextBase 之类的内容设置依赖项覆盖,这些内容仅对该请求管道可见,并且可以传递给您的 Presenter 构造函数。

    IoC 还允许您将其他依赖项注入到您的 Presenter 中,以帮助保持它的轻量级。通过这种方式,您可以将业务和数据访问权限移至其他层。

    MVP 在您必须使用 WebForms 时非常有用,例如大多数 CMS 系统。如果您不受限制,请使用 MVC.Net 进行新的 Web 开发。

    更新:正如所承诺的,这是一个相当的decent example。它缺少的一点是依赖项覆盖,可以这样完成:

    var dependencies = new DependencyOverrides
                        {
                            {typeof (HttpRequestBase),new HttpRequestWrapper(Request)},
                            {typeof (HttpResponseBase),new HttpResponseWrapper(Response)},
                            {typeof (IPrincipal),Context.User},
                            {typeof (IIdentity),Context.User.Identity},
                            {typeof (IUserProfile),Context.User.Profile},
                            {typeof (HttpSessionStateBase),new HttpSessionStateWrapper(Session)}
                        };
    
    presenter = container.Resolve<TPresenter>(dependencies);
    

    【讨论】:

    • 好的!我做了一些完全不同的事情。我为什么要把事件连接到演示者?我什么时候可以从我的视图和我想要的任何事件处理程序中调用演示者方法?
    • 您可以将它们连接起来,以便将更多的逻辑转移到 Presenter,并且减少对 View 做正确事情的依赖。视图应该尽可能的愚蠢。这是因为您无法轻松地对 ASPX View 实现进行单元测试,但您可以存根 View 接口并将其注入 Presenter 进行单元测试。验证、绑定等都可以在 Presenter 中完成,但是使用 View 来访问属性和触发状态更改。
    • 没有问题,我相信一些 cmets 会引发关于 MVC 与 MVP 的大规模辩论,因为每个人都有自己的看法。它们都是有效的模式,我个人会选择 MVC,因为它更严格(视图无法反驳),并且内置在框架中。两者都提供了一种分离关注点的方法,这是它们的主要目的。
    • 我认为你的意思是视图不能在 MVP 中回话,因为在 MVC 中,视图同时与模型和控制器对话。
    • 我的意思是在 MVC 中,视图不与控制器对话 - 路由将请求直接发送到控制器。在 MVP 中,视图确实将详细信息传递给演示者,然后演示者可以告诉它要做什么。 See diagram here
    【解决方案2】:

    您选择了 Web 表单而不是 ASP.NET MVC 框架,从而犯了一个架构错误。 2003 年的类型数据集也是如此,您应该使用实体框架。与时俱进!

    【讨论】:

      【解决方案3】:

      你看过ASP.NET MVC吗?这是模型-视图-控制器模式,将为您处理所有路由和管道。使用DataAnnotations 可以轻松进行模型验证,还有很多ResourcesTutorials

      或者是否有特定原因需要在经典 ASP.NET 中使用 MVP 模式?

      【讨论】:

        【解决方案4】:

        由于您的问题不是关于 MVC 与 MVP 或类型化数据集与实体框架的优点,我假设您有令人信服的理由以您的方式做事。

        除此之外,您似乎没有做错任何事情。使用 MVP,验证应该在 Presenter 实现中进行,因为它们可以在回发期间访问您的视图实例。当然,您也可以使用 javascript 进行客户端验证。

        【讨论】:

        • 我希望您不建议取消服务器端验证。
        • @TheCodeKing:不,我不知道。你从哪里得到的?
        • 只是关于客户端验证的最后一句话。除了作为替代品之外,似乎有点随机。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-02
        • 2018-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多