2010-04-27 25 views
12

我正在使用S#arp架构,但我不记得自己在哪里读过它,但他们说他们的ViewModels应该存储在服务层,并且您的视图应该将视图模型提交给服务进行处理。哪一层应该构建一个视图模型?

我的问题是这样的。哪一层应该构造ViewModel?它应该在服务层,并且控制器要求它吗?或者控制器应该自己构造它?还有一个关于更新视图模型的问题,就好像它包含集合,并且模型状态无效,您还需要重新生成任何列表。

有什么建议吗?

非常感谢

马特

回答

8

创建视图中的控制器模型。控制器获取域实体(通过模型绑定器从数据库中检索),可能位于其他视图模型中,联系存储库以获取其他数据,创建新视图模型并将其传递给适当的视图(或重定向)。所以控制器的责任是根据输入域数据准备视图/视图模型(并且当然处理错误)。

您可以看看here,以替代在控制器中创建视图模型。这种技术将视图模型创建移动到动作之外,这样不仅控制器动作接受纯域对象,而且还返回纯域对象。我不会说在所有情况下它都是合适的,但学习起来非常有趣。

以上与AutoMapper相关的技术也引发了类似于“我应该将视图模型传递给服务层”的问题。不,你不知道。如果您需要将复杂对象传递给服务或域图层,请在相应的服务/域图层中定义此对象,然后使用它将数据传递到这些图层。这个对象可以很容易地映射到/从视图模型(例如,使用AutoMapper)。但是你的低层(服务/域)不应该耦合到上层(视图/控制器)。不是在这种情况下,不在其他人中。从来没有低层次的图层应该依赖于它们上面定义的东西

+0

那差不多就是我现在做的,但我必须做的事情错误,因为当把视图模型转回到域时,我似乎有很多条件逻辑。也许我需要将我的观点分解成更小的块。 – 2010-04-29 09:04:15

+0

我目前有一个编辑视图,它根据实体的状态添加适配。我会为不同的州创建多个视图更好吗? – 2010-04-29 09:05:29

+0

没有看到您的编辑视图和模型,这很难回答。 – queen3 2010-04-29 10:27:56

3

这些文章可能是有趣的你:

DDD : Command Query Separation as an Architectural Concept

Better Application Services and CQS using S#arp Architecture

有与在服务层的视图和表单模型第二制品相关的示例应用程序,而不是控制器。

+1

这是正确的答案。但是,我通常从控制器中的ViewModel开始,随着控制器的发展将其迁移到服务层。 – 2010-07-01 22:15:41

+0

链接在moent下,也许http://sharp-architecture.readthedocs.io/en/latest/additional-resources/additional-information.html会有帮助吗? – kristianp 2017-07-13 00:24:53

0

也看看Who Can Help Me - 这太棒了。这个框架基于S#arp架构。它有很多关于View/Form/Edit viewModel的指导。

11

根据传统方法或理论上的明智,ViewModel应该是用户界面层的一部分。至少这个名字是这么说的。

但是当你开始用Entity Framework,MVC,Repository等自己实现它时,你会意识到其他的东西。

有人必须将实体模型与ViewModel进行映射(最后提到的DTO)。这应该在A)UI层(由控制器)还是在B)服务层完成?

我使用选项B.选项A是一个不可能的,因为几个实体模型组合在一起形成ViewModel的简单事实。我们可能不会将不必要的数据传递到UI层,而在选项B中,服务可以使用数据进行播放,并且在映射(到ViewModel)后仅将所需/最小值传递到UI层。但是,让我们假设我们使用选项A,将ViewModel放入UI层(以及Service层中的实体模型)。

如果服务层需要映射到ViewModel,那么服务层需要访问UI层的ViewModel。哪个图书馆/项目? Viewmodel应该位于UI层的单独项目中,并且该项目需要由服务层引用。如果ViewModel不在单独的项目中,那么就有循环引用,所以不行。服务层访问UI层看起来很尴尬,但我们仍然可以应付它。

但是如果有另一个UI应用程序使用此服务呢?如果有移动应用程序会怎么样? ViewModel有多不同?服务应该访问相同的视图模型项目吗?或将所有的UI项目竞争?

经过这些考虑,我的答案是将Viewmodel项目置于服务层。无论如何,每个UI层都必须访问服务层!并且可能会有很多类似的ViewModel,他们都可以使用(因此映射对于服务层来说变得更容易)。现在映射是通过linq完成的,这是另一个好处。

最后是关于DTO的讨论。还有关于ViewModels中的数据注释。带有数据注释的ViewModels不能驻留在服务层中。那么DTO将是ViewModel的精确副本,并且两者之间有一对一的映射关系(比如AutoMapper)。 DTO仍然具有用于UI(或多个应用程序)所需的逻辑并驻留在服务层中。 UI层ViewModel只是复制DTO中的数据,并添加了一些“行为”(例如:属性)。

虽然没有直接关系到这个问题。 “视图模型外墙”在此提到必须注意channel 9 link(另一视图模型内部视图模型)&“命令”也值得探讨(@ 11:48启动)

相关问题