【问题标题】:MVC Mapping between View Model and Request-Response messaging pattern视图模型和请求-响应消息模式之间的 MVC 映射
【发布时间】:2015-02-24 23:50:28
【问题描述】:

我有以下 MVC 设计模式问题,不知道该走哪条路。

在 UI 层中,视图模型用于控制器操作方法。很酷。

Service层使用Request-Response消息模式,所以服务类方法有一个Request对象作为参数(in),方法返回一个Response对象(out)。此方法调用带有域对象参数的存储库方法。换句话说,要调用服务方法,您需要用您的数据填充 Request 对象,该方法在 Response 对象中返回结果,即请求-响应消息。

要将视图模型中的数据传递给服务方法中的域对象,AFAIK 有两个选项:

  1. 确保 Request 对象包含与 View Model 属性相同的属性,然后您可以将 View Model 中的值(手动或自动)映射到 Request 对象。
  2. Request 对象包含 View Model 的属性,即 View Model 的实例现在位于 Request 对象中(与上述选项不同 - 只有一个属性)。现在您可以简单地将 View Model 分配给 Request 对象中的属性。

我发现这两种方法都有缺陷...

在选项 1 中,如果 View Model 有许多属性,并且您正在使用映射器(例如 AutoMapper),则在 Controller 方法中,您需要将属性从 View Model 自动映射到 Request 对象。然后在服务层,在服务方法中,您需要将 Request 对象中的属性自动映射到 Domain 对象。两级映射 - 非常错误!

在选项 2 中,Request 对象包含一个包含视图模型的属性。然后,您可以轻松有效地将 Request.vm(属性)自动映射到 Domain 对象,但出于某种原因,这对我来说看起来像是糟糕的设计!我很担心这种设计。

哪种方法最好?还是有另一种更好的方法来映射 VM 和 R-R 模式?

【问题讨论】:

  • 这就是为什么我更喜欢实体框架,因为它允许我创建模型。我对所有东西都使用强类型,因此没有自动映射的问题。对于您的情况,选项 2 可能是最好的,因为它遵循“优先组合优于继承”原则。也就是说,您的 Request 对象“包含”您需要的 vm 属性。
  • @JohnPeters 我正在使用 EF、域模型模式和存储库模式。你能解释一下你是如何在 UI 层使用强类型而不是视图模型的吗? (如果我理解正确的话)。谢谢。
  • +1 得到很好解释的有效问题。如果您添加一些代码示例(非常简单),可能会更容易理解。
  • @SBirthare 谢谢 :) 是的,我通常将代码放在问题中,但今天急于解决问题。
  • @ThomasVeil 我在整个设计中使用 EF Poco 类。一切都与数据有关,而且数据很容易建模为即使在 SQL 层也能理解的 POCO 类。 ViewModel 只是根据用户对他们想要做什么的响应启动适当的查询。这使得控制器除了提交 POST 之外几乎没有任何逻辑。这就是为什么我所有的虚拟机都有一个名为 Post 的方法。 Post 方法不需要任何参数。传入是因为选定的值已绑定到属性并且已经存在。

标签: asp.net-mvc design-patterns automapper asp.net-mvc-viewmodel


【解决方案1】:

Request/Response 是一种 messaging 模式,但您似乎没有使用消息.. 而是使用对象。这是你问题的真正症结所在。您使用的模式不正确,更重要的是,您似乎使用了错误的模式来完成这项工作。为什么在这种情况下需要消息传递?对于简单的多层应用程序来说,这只是额外的开销。

如果您真的想使用消息传递,您可能应该将数据序列化为 json 或 xml,将其传递给您的服务,然后将数据反序列化为您在该层中使用的任何对象。这样就不需要对其他层的数据类型有任何依赖了,因为(反)序列化过程不一定需要这种依赖。

就个人而言,我会避免整个消息传递方面,并在您的视图模型和域对象之间映射一个映射层,然后使用域对象调用您的服务层。

【讨论】:

    【解决方案2】:

    在您上面描述的场景中,我没有 Request 对象。

    我只是使用来自服务层 -> 表示层的域对象(PO​​CO 类/实体)。

    在准备来自控制器的响应时,我使用 AutoMapper 将从服务层返回的域对象转换为 ViewModel 对象。

    如您所见,通过上述方法,选项 1 不再是问题。域到虚拟机,反之亦然,配置一次就完成了。

    当一个 Web 请求进来时,它有一个 ViewModel 对象,该对象在传递给服务层之前转换回域模型。

    我不确定您是否可以将其视为“另一种”或“更好”的模式。如果您觉得这个想法不错,我可以在需要时提供更多信息。

    【讨论】:

      猜你喜欢
      • 2014-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多