首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我应该如何将我的商业模式与我的观点结合起来?

我应该如何将我的商业模式与我的观点结合起来?
EN

Stack Overflow用户
提问于 2013-12-10 12:53:29
回答 2查看 116关注 0票数 1

我在成长过程中遇到了一个有趣的问题。现在,我使用一个与数据库无关的工作层单元来抽象我的ASP.MVC 4 web应用程序中实际数据库依赖项中的数据访问。

实现工作单元接口的每个单独的数据库项目都知道我的业务模型(直接进入或离开数据库的模型)。我不太清楚我对这种方法的看法,但这不是我要问的问题。

我是否应该使用像AutoMapper这样的解决方案将业务模型转换为/从域模型--传递到视图并用于任何不应该访问数据库字段(即ID)的工作中的模型?

例如,在我的BusinessModels项目中,我有以下类

代码语言:javascript
复制
BusinessModels
    /UserAccounts/
         User.cs
           - ID
           - Username
           - HashedPassword
           - Salt
         UserSettings.cs
           - IsSubscribedToNewsletter
           - AllowDirectEmails

将这些用户和UserSettings模型绑定到使用AutoMapper这样的单个模型有意义吗?

代码语言:javascript
复制
MyProject
   /DomainModels/
       User.cs
          - Username
          - HashedPassword
          - Salt
          - IsSubscribedToNewsletter
          - AllowDirectEmails

为了表达自己的观点?

这个问题也扩展到了非MVC项目,但是我觉得当我正在开发一个MVC项目时,在这个标签中问它会更有意义。

TLDR是否有必要映射业务模型/实体来查看模型,或者是否提供了不必要的抽象层?如果是这样的话,存储库是包含业务模型还是视图模型(这些模型自动映射到底层的业务模型)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-10 16:19:20

您可以将视图模型用于两种不同的事情:

  • 呈现一个新视图(获取操作),将视图模型对象作为视图的模型传递
  • 在Post (POST操作)中,使用视图模型作为参数,从视图中接收数据

(我知道,第二个问题是有争议的。但是,使用视图模型来实现这一点并不奇怪)

GET操作的模型需要所有必要的属性来呈现视图:

  • 正在显示/编辑的实体的值
  • 呈现视图所需的额外值(例如,下拉列表的SelectLists )

假设您有一个可以属于一个UserGroup的用户。

在这种情况下,如果要编辑用户,模型需要:

  • 用户数据
  • UserGroups列表

我会用这样的模型:

代码语言:javascript
复制
public class EditUserModel
{
   public User User {get;set;}
   public SelectList UserGroups {get;set;}
}

如您所见,我直接将用户添加为属性。但是我没有将类别列表作为属性添加,因为我不需要整个类别列表,并在视图中包含它们的所有属性。此外,如果您对控制器进行单元测试,则可以验证SelectList是否如预期的那样(如果在视图中创建用户组列表,则无法做到这一点)。

但是,如果您不需要视图中用户的所有属性怎么办?是否值得删除用户属性,并为名称、电子邮件、JoinedData、Active.?我认为答案是否定的。假设您添加/删除或重命名了一些用户实体属性。如果视图模型中有单独的属性,那么在更新视图之前,还必须对它们进行更改。而且,如果您依赖于自动映射(自动映射器、值注入器),那么如果您犯了一些错误,您甚至都不会意识到。

我还说过,视图模型可以用于将数据回发到控制器。所以你可以这么做:

代码语言:javascript
复制
[HttpPost]
public ActionResult Edit(EditUserModel userModel)

如果这样做,模型绑定将使用窗体控件中的值填充userModel。所以你会得到一个半空的模型。在这种情况下,UserGroups列表将为null,并且,取决于您编辑的用户属性的数量,用户还可以拥有许多空/非初始化属性。

为了避免出错,在某些情况下,建议创建一个不同的模型(可能还包括辅助类),以明确预期将发布到模型中的内容。

例如,如果您有一个操作来显示整个用户数据,但它只允许更改其密码,则可以创建一个具有两个属性的类: password和PasswordConfirmation。

在这种情况下,POST的视图模型只能具有密码和PasswordConfirmation。并导出具有此继承属性的GET模型,以及用户组和用户列表。

为什么要继承和不使用独立的类?仅仅因为当您使用类似于Html.TextBoxFor(m => m.User.Name)的东西时,Model将能够设置用户属性的Name属性,但前提是post操作的参数具有相同的结构。也就是说,如果get的视图模型具有以下结构:

代码语言:javascript
复制
public ChangePasswordModel
{
   public string Password {get;set;}
   public string PasswordConfirmation {get;set;}
   // extra properties, like the list of user groups, the user data...
}

这个职位的模型有这样的结构:

代码语言:javascript
复制
public PostedChanegPasswordModel
{
   public User User {get;set;}
}

Html.TextBoxFor(m => m.EditedUser.Name)呈现的输入的内容不会绑定到PostedEditViewModel的User.Name

但如果你做这个:

代码语言:javascript
复制
public EditUserModel : PostedEditUserModel
{
   // extra properties, like the list of user groups
}

数据将被绑定,不会有任何问题。

一般情况下,您必须小心您使用的模型,以张贴和获取。我建议使用和蜜罐一样多的不同的视图模型。

何时使用自动属性映射到全新的视图和不同的模型?

您一定有一个非常强烈的理由有不同的视图模型。这可能是在外部(即先设计)启动应用程序的结果,或者是因为一个团队在实现业务logie之前或期间正在开发UI。

在这种情况下,您可以发现视图模型的类和视图本身已经定义好了,它们与实体非常相似,但并不完全相等。这是一个例子,当我认为它可以是好的使用映射器。

使用不同类的另一个原因是将接口与逻辑分离。但这通常只发生在前一种情况下。

票数 1
EN

Stack Overflow用户

发布于 2013-12-10 12:59:14

考虑到视图模型,我将它们视为您希望使用的数据的摘要。

因此,以您的示例为例,您的视图模型将包含来自UserUserSettings类的数据。假设您有一个名为UserData.cshtml的视图,那么我会将其编码如下:

代码语言:javascript
复制
public class UserDataViewModel
{
    public string Username { get; set; }
    public bool AllowDirectEmails { get; set; }
    // etc ...
}

public ActionResult UserData()
{
    var viewModel = new UserDataViewModel();

    viewModel.UserName = "Whatever";
    viewModel.AllowDirectEmails = false;

    // Or however you get the data for the user.....

    return View(viewModel) 
}

希望你能明白。因此,将外部类中的信息合并到一个viewmodel类中是正确的。基本地将视图模型类中的所有内容连接在一起。

我将viewmodel类命名为与它将要用于的视图相同。这可以帮助文档,并使新开发的代码更容易遵循。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20495136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档