我有 50+ 个基本数据类,并希望使用一致的方法以 3 或 4 种不同的格式显示这些类。
我知道大多数专家建议使用 ViewModels
. 有些人甚至建议每次观看一个。
但是,通过直接在数据模型上使用不同的DisplayTemplates
,可以肯定的是,要创建/维护的代码会更少。
例如,比较以下 3 个分配:
<小时 />1:没有视图模型,使用不同格式的显示模板
class Person
{
public int ID {get;set;}
public string FirstName {get;set;}
public string LastName {get;set;}
public string NickName {get;set;}
public string Nationality {get;set;}
public string FavouriteColour {get;set;}
public string FavouriteBand {get;set;}
}
@Html.DisplayFor(m => m.Person, "Simple")
@Html.DisplayFor(m =>m.Person, "Full")
这似乎是最简单的选项,需要创建和维护的代码最少。
<小时 />2:仅在偏离数据模型时使用视图模型
class Person
{
public int ID {get;set;}
public string FirstName {get;set;}
public string LastName {get;set;}
public string NickName {get;set;}
public string Nationality {get;set;}
public string FavouriteColour {get;set;}
public string FavouriteBand {get;set;}
}
class PersonSimpleViewModel
{
public int ID {get;set;}
public string NickName {get;set;}
public string Nationality {get;set;}
}
@Html.DisplayFor(m => m.Person)
@Html.DisplayFor(m => m.PersonSimpleViewModel)
这将需要为每个实体提供一个额外的虚拟机,以及使用/配置像AutoMapper或ExpressMapper这样的系统。
我觉得这不必要地增加了复杂性。此外,x x x 50 个实体,需要创建/维护的代码要多得多。
<小时 />3:每种显示格式的视图模型
class Person
{
public int ID {get;set;}
public string FirstName {get;set;}
public string LastName {get;set;}
public string NickName {get;set;}
public string Nationality {get;set;}
public string FavouriteColour {get;set;}
public string FavouriteBand {get;set;}
}
class PersonSimpleViewModel
{
public int ID {get;set;}
public string NickName {get;set;}
public string Nationality {get;set;}
}
class PersonFullViewModel
{
public int ID {get;set;}
public string FirstName {get;set;}
public string LastName {get;set;}
public string NickName {get;set;}
public string Nationality {get;set;}
public string FavouriteColour {get;set;}
public string FavouriteBand {get;set;}
}
@Html.DisplayFor(m => m.PersonSimpleViewModel)
@Html.DisplayFor(m => m.PersonFullViewModel)
此选项需要的代码最多,而且感觉很愚蠢,因为Full
VM 与数据模型相同。
但是,我更喜欢这个而不是 2,因为它是一致的 - 每种显示格式都有其相应的 VM,并且数据模型无处可见。
如果不了解有关应用程序或其要求的更多细节,很难说是否应该创建视图模型。您有一个选择是避免它们并使用实体类,直到您意识到需要视图模型。
。x x 50 个实体,需要创建/维护的代码要多得多。
不确定我是否同意这个论点。创建每个视图模型类最多只需几分钟。假设创建每个视图模型需要 5 分钟,再花 5 分钟将其连接到 Automapper 或 ExpressMapper。每个实体为 10 分钟。如果你每小时休息 10 分钟,你每小时可以完成其中的 5 个,这意味着 10 个小时来完成所有这些。这比一天多一点的工作(你可能不应该一次完成所有工作,而是根据需要零碎地完成(。
还要记住,实际上您可能不需要为每个实体创建一个视图模型,您需要为每个视图创建一个视图模型。通常,要向用户呈现的数据是 2 个或更多实体的串联。如果需要这些视图模型进行数据输入,则连接参数可能不适用,但其他参数适用。例如,如果要将属性应用于视图模型,以便可以对其应用序列化或验证规则,该怎么办?您不希望在实体类上添加这些属性,因为它负责数据存储,而不是用户输入序列化或验证。
然后是派生属性。假设您的一种观点,您想为您的Person
拥有DisplayName
房产。您会向您的实体添加类似以下内容的内容吗?
public string DisplayName => $"{FirstName} ({NickName}) {LastName}";
为什么要用你只需要的东西来污染数据存储类,当你向用户呈现数据时?
我觉得这不必要地增加了复杂性。
可能是,这就是为什么我说这是一个很难回答的问题,而不了解有关您的应用程序的更多详细信息。这些视图模型对我来说实际上只是"数据桶",所以我真的不认为它们很复杂。也就是说,维持这种分离需要额外的成本。像任何事情一样,该成本是否合理取决于您能够从中获得什么理想的好处。
以下是一些一般指南。
仅在显示实体时使用实体。将实体传递到视图的最大问题是何时允许以某种方式修改该实体。如果只是数据显示为只读,请务必使用该实体,而不必担心额外的类。
在接受用户输入时使用视图模型。您希望从视图模型映射到实体的额外步骤允许您根据需要清理用户输入,然后只能允许修改应允许修改的属性。
除此之外,请在有意义的情况下使用视图模型。如果需要对某些属性执行某种复杂的处理才能显示它们,则视图模型是该逻辑的好地方。或者,您可以使用视图模型来简化属性访问。基本上,使用视图模型,这样做可以减少视图中需要的逻辑量。您的视图应具有尽可能少的逻辑,视图模型通常可以帮助解决这个问题。