我应该使用 DTO 作为 MVVM 中的数据模型吗?

2024-01-07

我目前正在研究我第一次真正尝试使用 MVVM,并且一直在阅读各种关于如何最好地实现它的文章。

我当前的想法是有效地使用我的数据模型作为数据传输对象,使它们可序列化并让它们同时存在于客户端和服务器端。 这似乎是一个合乎逻辑的步骤,因为这两种对象类型实际上只是属性 getter 和 setter 的集合,而中间的另一层似乎完全是多余的。

显然,INotifyPropertyChanged 在服务器端无法正常工作会出现问题,因为没有要通信的 ViewModel,但只要我们小心地从服务层中的数据模型构建正确的域模型对象,而不是处理服务器端的数据模型我认为这不应该是一个大问题。

我在阅读中没有找到太多关于这种方法的信息,所以我想知道这是否是一个非常标准的事情,这是否只是假设为在多层环境中执行 MVVM 的事实上的方式? 如果我对事物的想法完全错误,那么对其他方法的想法也会受到赞赏。


您可以使用任何您觉得舒服的模型,是的,您的所有属性都需要 INotifyPropertyChanged 行为。这将如何影响服务层完全取决于您的实现。

我假设您的意思是您认为您绑定到 DTO?

我的看法是,应用程序各层之间存在阻抗不匹配,这是您的 领域模型可能看起来与关系模型类似,但存在细微但至关重要的差异。还有 域模型和 DTO 之间不匹配(对象可能被展平、计算属性等……)。直接绑定到 DTO 很诱人,因为它们可能被设计为具有特定操作所需的内容,但是 DTO 与视图所需的阻抗之间也存在不匹配,以实现预期的结果。这就是视图模型的用武之地。视图模型负责将 DTO 属性代理给视图,负责让视图知道是否存在验证错误,并将命令路由到适当的处理程序(保存、删除等) ,...)。

我倾向于按以下方式进行设置:

// POCO object. Serializable.
public class AddressDto 
{    
   public int Id { get; set; }
   public string Street { get; set; }    
   public string City { get; set; }    
   public string Country { get; set; } 
}

// IDataErrorInfo for validation.
public class AddressViewModel : INotifyPropertyChanged, IDataErrorInfo
{
   private readonly AddressDto addressDto;

   public AddressViewModel(AddressDto addressDto)
   {
      this.addressDto = addressDto;      
   }

   public int Id { /* get and set for property changed event and update dto */ }
   public string Street { /* get and set for property changed event and update dto  */ }
   public string City { /* get and set for property changed event and update dto  */ }
   public string Country { /* get and set for property changed event and update dto  */ }
   ...

   // IDataErrorInfo implementation
}

public class EditAddressViewModel : INotifyPropertyChanged
{
   public AddressViewModel Address { /* get and set for property changed event */ }
   public ICommand Save { /* setup command */ }
   public ICommand Cancel { /* setup command */ }

   private void Save()
   {
   }

   private void Cancel()
   {
   }
}

然后,您的 EditAddressView 将绑定到 EditAddressViewModel。基本上,规则是所有 UI 行为都应该用视图模型来表达。

是的,这确实意味着额外的工作,但是您可以采取一些措施来简化事情(代码生成等)。我实际上正在开发一个库,旨在使用流畅的 api 简化整个 MVVM 流程。检查一下:http://fluidviewmodel.codeplex.com/ http://fluentviewmodel.codeplex.com/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我应该使用 DTO 作为 MVVM 中的数据模型吗? 的相关文章

  • 过滤项目来源

    通过此代码 我设置了数据网格的 ItemsSource 不过 我有更多的 wpf 控件来过滤数据网格 例如从时间范围过滤数据网格 我可以为此编写一个新查询 但这似乎没有必要 因为数据已经可用 我只需要过滤它 最好的方法是什么 我能得到的任何
  • 是否可以仅突出显示图像的某些部分(不透明度)?

    我已对图像应用了不透明度 这是代码
  • 获取程序集中所有资源的列表

    我有一个文件夹Resources并想要获得一份包含所有内容的列表paths 如果我将它们设置为embedded resource 我可以通过 var resources Assembly GetExecutingAssembly GetMa
  • 如何将 WPF 3.0 下构建的应用程序转换为 4.5 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我在 WPF 3 0 中构建了一个应
  • 带有移动向前/向后按钮的自定义列表框

    我有一个带有左 右重复按钮的自定义列表框 可以使用内容模板滚动其内容 如下所示
  • 数据绑定到代码隐藏中的目标 CLR 属性

    在代码隐藏中绑定到依赖属性很容易 你只需创建一个新的System Windows Data Binding对象 然后调用目标依赖对象的SetBinding method 但是 当我们绑定的属性是 CLR 属性并且您无法提供Dependenc
  • 内容更新时自动调整列表视图列的大小

    我试图让列表视图中的 gridviewcolumns 在更新绑定源 视图模型上的可观察集合 时自动调整内容大小 列表视图填充正常 但当我刷新 更新集合时不起作用 这是我到目前为止正在尝试的解决方案 XAML
  • 如何在Phone类库项目中添加ResourceDictionary并访问它

    我正在开发一个项目 其中我有一个引用图书馆项目的子项目 在我的库项目 电话类库 中 如何创建 ResourceDictionary xaml 其中我需要添加一些样式并在 xaml 文件和 cs 文件中使用它 我需要访问 xaml 文件中的
  • 在表格中可视化 2D 数据

    我需要一些帮助并且需要指出正确的方向 我正在创建一个应显示二维数据的 WPF 应用程序 它应该显示如下 y x 1 2 3 4 5 1 1 2 3 4 5 2 2 4 6 8 10 3 3 6 9 12 15 4 4 8 12 16 20
  • 从 BitmapImage 获取支持的图像格式

    如何获取 System Windows Media Imaging BitmapImage 支持的图像格式列表 我正在用 C WPF 编写一个简单的图像处理工具 BitmapImage 类是更有用的位图类之一 因为它能够从多种格式进行解码
  • 在 MVVM 中使用 LiveData 进行观察时,如何在 onChanged() 上编写单独的代码? [未解决]

    所以 我实施了 public class DriverLoginActivity extends BaseActivity implements Observer
  • 如何识别单击的按钮属于哪个列表框项?

    在 WPF 编程中 我在编写按钮单击事件处理程序时遇到问题 因为该按钮位于列表框项目 数据模板的一部分 内 当单击该按钮时 我无法判断它属于哪个项目 有什么解决办法吗 求救 您似乎已将列表框绑定到集合 并且您的按钮是数据模板或项目模板的一部
  • GridViewColumn 中的 WPF 文本格式设置

    我想将格式 对齐文本 货币格式 0000 00 应用于 GridViewColumn 中的列
  • 使用backgroundworker手动停止调试

    我正在编写一个 WPF C 项目 使用BackgroundWorker 带有进度条的弹出窗口 我开始调试 F5 键 来检查我的程序 之后BackgroundWorker完成并关闭弹出窗口 关闭MainWindow不会自动停止调试过程 我必须
  • WPF 对 DataGrid 内的 TextBlock 进行全局样式设置

    我遇到了一个非常奇怪的问题 我正在尝试将全局样式应用于一个中的多个控件DataGrid 它们中的大多数完全按照我的预期工作 然而 对于TextBlock永远不会被应用 样式为ComboBox TextBox Label 和其他几个都被应用到
  • WPF 自定义控件 - ItemsControl 模板未应用

    我正在构建一个派生自 TabControl 的自定义 WPF 控件 在 ControlTemplate 中 我使用 ItemsControl 来显示从模板绑定的列表 FileMenuItem 类型的可观察集合 在程序执行期间 我在输出窗口中
  • Prism 7. 将 PrismApplication.CreateShell() 与非 Window 控件一起使用

    我想从 6 3 更新到 7 我似乎遇到了障碍 在 App xaml 中使用 PrismApplication 类时 CreateShell 期望返回类型为 Window 而不是之前需要 DependencyObject 的 BootStra
  • 属性和依赖属性有什么区别

    依赖属性的创建方式与属性相同 依赖属性是否仅在创建自定义控件时使用 依赖属性和标准属性有很大不同 依赖属性提供的关键功能是支持binding and 动画片 如果您想使用Binding或模板绑定该属性需要是依赖属性 当对属性进行动画处理时
  • 从另一个命令 Handle() 方法中调用命令

    嗨 我正在使用简易注射器 https simpleinjector orgDI 库并一直在关注一些关于围绕命令模式设计的架构模型的非常有趣的材料 同时 在我的架构的命令方面 https cuttingedge it blogs steven
  • WPF 中的填充弧

    I am trying to draw a figure something like this 我需要为每个弧段都有一个独特的元素 我可以根据需要处理事件并重新着色 我有点不确定如何在 WPF 中创建正确的几何图形 我可以根据圆的半径和与

随机推荐

  • Python 多进程、日志记录、各种类

    我目前正在尝试从多个进程登录到单个文件 但遇到了很多麻烦 我花了无数个小时在网上查找 stackoverflow 和 Google 但没有得到任何具体的结果 我读过了 在 Python 中使用多处理时应该如何记录 https stackov
  • 为什么这些是==而不是`equals()`?

    我对Java的处理方式有点困惑 and equals 到那个时刻int Integer和其他类型的数字 例如 Integer X 9000 int x 9000 Short Y 9000 short y 9000 List
  • mysql 连接错误“字典中不存在给定的键”

    我在使用 ADO NET Driver for MySQL Connector NET 连接到 mysql 数据库时遇到问题 我得到了这个异常The given key was not present in the dictionary E
  • 搜索实现特定接口并执行方法的类

    我想调用实现某些特定接口的类中的方法 我已经尝试和搜索了很多 但不知道该怎么做 这是我的想法 但它不起作用 希望可以有人帮帮我 getting the list List
  • Java String 的默认初始值是多少?

    考虑一个名为的 Java 字符串字段x 的初始值是多少x当为类 x 创建对象时 我知道对于int变量 默认值指定为0 在创建实例时 但会变成什么String 如果您不执行任何操作 它会初始化为 null 所有引用类型也是如此
  • android在对话框中加载webview [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在我的 webview 中打开 twitter auth 而不是在浏览器中打开 有什么好的教程如何在
  • 用 Beautiful Soup 解析 XML

    编辑 已解决 我想我应该在底部添加我的答案 注意 所需的输出是一堆像 US D0591026 我的 XML 数据如下所示
  • 比较两个 C 风格字符串的正确函数是什么?

    所以我陷入了两难的境地 我需要比较两个 C 风格的字符串 并搜索了最合适的函数 memcmp Compare two blocks of memory function strcmp Compare two strings function
  • 使用免费的第三方 dll 将 word 转换为 pdf

    我想将word文档转换为pdf 我找到了很多使用 Office dll 的解决方案 但我想要一个使用免费第三方dll的解决方案 因为在office dll中必须安装office 所以我的服务器上没有安装office 有没有免费的第三方dll
  • 将组合变音符号转换为简单 utf

    由于某些编码问题 我在将字符串插入数据库时 遇到问题 字符串源是外部 rss 提要 在网络浏览器中看起来没问题 即使在调试器中 文本也看起来没问题 如果我将strong复制到记事本中 结果也可以 但在记事本 中可以看到字符串正在使用组合字符
  • 如何从 Android 调用 PHP 函数?

    我想调用服务器上的特定 php 函数并发送一些参数 到目前为止 我实现了可以使用 HttpClient 打开 php 文件并执行数据传输到 Json 并在我的应用程序中显示 那么 现在我希望能够调用特定函数并向其发送参数 我该怎么做 抱歉
  • Oracle 和分页

    在 MySql 中 分页的概念可以通过使用单个 SQL 语句轻松实现LIMIT子句类似于以下内容 SELECT country id country name FROM country c ORDER BY country id DESC
  • 无法使用 MongoEngine Pymongo 和 Django 返回 JSON 对象?

    所以我试图返回一个项目的 JSON 对象 我花了几个小时试图让 Django 返回 JSON 这是我们一直在研究的观点 def json request first name user User objects all user User
  • ASP.NET MVC AJAX 与 HTML.ValidationMessageFor

    我习惯使用 ASP NET Webforms 通过 UpdatePanels 执行 AJAX 的简单方法 我知道这个过程对于 MVC 来说更加手工 在特定情况下 我使用数据注释来验证某些表单输入 我使用 HTML ValidationMes
  • 如何全局更改Swing JTextFields的ActionMap?

    我想通过用我的自定义实现替换一些操作来更改整个应用程序中 Swing JTextFields 的 ActionMap 关于原因的解释可以参考以下帖子 如何使 JTextComponent 的插入符跳过选定的文本 https stackove
  • 如何在悬停时反转转换?

    我可以通过 CSS 反转悬停时的过渡动画吗 当我将鼠标悬停在 菜单 文本上时 我需要滑动到右侧蓝线 并在 400 毫秒延迟后从左侧灰线滑动 是否可以 menu display inline block position relative f
  • 是否有像 phpMyAdmin 这样的工具可以配置为仅访问单个数据库? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有像 phpMyAdmin 这样的工具可以配置为仅访问服务器中的单个 MySQL 数据库 我无法使
  • Bootstrap Dropdown 在 React 中不起作用

    我从引导下拉列表中添加了一个用于 React 的下拉按钮 但它不起作用并显示为普通按钮 你能给我一个解决方案吗 div div
  • Ajax.BeginForm 指定“GET”类型发帖

    我的看法如下 Scripts jquery unobtrusive ajax js type text javascript gt Scripts jquery validate js type text javascript gt Scr
  • 我应该使用 DTO 作为 MVVM 中的数据模型吗?

    我目前正在研究我第一次真正尝试使用 MVVM 并且一直在阅读各种关于如何最好地实现它的文章 我当前的想法是有效地使用我的数据模型作为数据传输对象 使它们可序列化并让它们同时存在于客户端和服务器端 这似乎是一个合乎逻辑的步骤 因为这两种对象类