C# 我应该在不同的视图中重用视图模型吗?

C# 我应该在不同的视图中重用视图模型吗?,c#,asp.net-mvc,viewmodel,C#,Asp.net Mvc,Viewmodel,我注意到我的视图需要与其他视图相同的信息。但有时需要视图模型的5个属性,有时只需要2个 您是在多个视图上共享此类视图模型,还是为每个视图创建一个独立的视图模型,或者您更喜欢继承或组合策略 对我来说,共享视图模型有一些缺点: 最小意外原则:只填充视图模型5的2个属性并获得null引用异常是很奇怪的,因为您不想查询数据库的其他数据。当视图模型有5个属性时,我希望所有属性都已填充。例外情况证明了这一规则 关注点分离/单一责任原则:视图模型在复杂的站点上杂乱无章,因为您必须满足每个视图的不同需求。如果涉

我注意到我的视图需要与其他视图相同的信息。但有时需要视图模型的5个属性,有时只需要2个

您是在多个视图上共享此类视图模型,还是为每个视图创建一个独立的视图模型,或者您更喜欢继承或组合策略

对我来说,共享视图模型有一些缺点:

  • 最小意外原则:只填充视图模型5的2个属性并获得null引用异常是很奇怪的,因为您不想查询数据库的其他数据。当视图模型有5个属性时,我希望所有属性都已填充。例外情况证明了这一规则
  • 关注点分离/单一责任原则:视图模型在复杂的站点上杂乱无章,因为您必须满足每个视图的不同需求。如果涉及到逻辑,它也会变得更复杂

  • 你觉得怎么样?您如何处理这种情况?

    我会为每个视图提供一个单独的视图模型。未使用的属性会降低代码的可读性(如果不使用该属性,为什么会出现该属性?)。如果您在多个视图上对一组固定属性具有相同的功能,我可以使用包含这些属性的基类来查看。

    我通常共享ViewModels。据我所知,使用视图模型的优势在于:(a)安全性,即应该隐藏的属性;(b)业务层和表示层之间的关注点分离。(b) 在共享视图模型时也是如此


    至于(a),我很少遇到在一个地方而不是另一个地方暴露财产是安全风险的情况。如果一个财产需要隐藏,它可能需要隐藏在任何地方。当然是YMMV,但这似乎是一个相当主观的问题。

    我首先使用实体框架和代码,因此我的域类需要保持相当严格,因为它们将映射到sql数据库

    有些视图只使用一个直接映射的实体,这非常好,所以我使用相同的域层实体。如果该实体需要更多信息(例如两个密码字段),我将使用composition组合应该比继承更受欢迎,所以如果您可以使用组合,通常因为它只是附加属性,所以可以使用组合


    如果有一个屏幕只使用该实体的两个属性,或者出于安全考虑我想隐藏属性,我将创建一个新的视图模型并只检索必要的数据。我将重用视图模型,但仅当其他视图中需要相同的属性时才使用。

    在我正在处理的项目中,每个视图都有自己的视图模型,但是我们也有CollectionViewModels,它们由多个视图模型共享/引用

    思考-供应商列表,需要在应用程序的多个屏幕中显示-并绑定到各种控件-列表框、网格视图,以及您需要的任何内容。只有一个ViewModel可以简化供应商列表的更新/刷新逻辑


    TLDR:如果所有用例都以相同的方式使用ViewModel,我只会重用视图模型。也就是说,它们都使用相同的属性等。

    人们倾向于根据其使用角度对ViewModel持有不同的理念。视图模型是视图和模型之间的粘合剂,人们通常会根据他们喜欢的两端中的哪一个来确定答案

    • 如果您希望模型/数据对象更为刚性,则倾向于将ViewModel与模型/数据绑定得更近,即,您将拥有一个在多个视图中使用的ViewModel,并让ViewModel根据您希望如何处理数据加载来确定要检索的属性(并延迟图像或其他长加载属性等)
    • 如果您希望视图更加僵硬,那么您将把ViewModel绑定到更靠近视图的位置,即每个视图都有一个单独的ViewModel,并让模型/数据对象在您从一个视图移动到另一个视图时处理诸如同步之类的事情

    就个人而言,我更喜欢第一种方法,因为我的数据往往更为严格,因为它不太可能像视图那样发生变化(在我的项目中——我认为这不是数据和视图的通用属性)。由于更改通知是ViewModels的一项自然功能,如果用户恰好有两个视图显示相同/相似的数据,我不必让我的模型对象传达更改。

    每个视图肯定有一个ViewModel,imho

    随着应用程序复杂性的增加,共享视图模型将趋于增长,当一个视图只需要一个属性时,将一个具有50个属性的对象传递给一个视图感觉并不好


    此外,有时您可能希望在ViewModel中添加绝对特定于您的视图且在其他视图中不需要的额外属性。假设您有一个依赖于ViewModel属性的CSS类。您不需要在视图中编写if-else语句,而是在ViewModel中创建一个返回正确CSS c的属性lass基于您拥有的任何业务规则。通过这种方式,您可以使视图尽可能精简,并且使用专用的ViewModel,您不会与真正不关心它的视图共享CSS类名。

    只有当所有视图都使用所有属性变量和方法时,我才会在多个视图之间共享VM,否则我将在中使用继承和抽象基本视图模型,如果这不能解决问题。执行1对1操作TLDR:是(如果您真的想使用它并且知道如何明智地使用它)

    我可以从视图模型层想到三个需要的职责:

  • 将视图层和模型层耦合在一起
  • 为单元测试提供接口
  • 当单个页面很复杂时,将逻辑分割成小块
  • 第一个责任实际上与t冲突