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

Jon*_*onC 11 architecture wpf mvvm dto

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

我目前的想法是将我的数据模型有效地用作数据传输对象,使它们可序列化并使它们存在于客户端和服务器端.这似乎是一个合乎逻辑的步骤,因为两个对象类型实际上只是属性getter和setter的集合,而介于两者之间的另一层似乎完全矫枉过正.

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

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

小智 5

您可以使用您认为合适的任何模型,是的,您的所有属性都需要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()
   {
   }
}
Run Code Online (Sandbox Code Playgroud)

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

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


Mic*_*ras 3

我不是这方面的专家。我也有同样的情况。我同意你的看法,这实在是太过分了。我已经使用这个解决方案有一段时间了,没有遇到任何问题。INotifyPropertyChanged 对我来说不是一个大问题,因为服务器端没有任何内容会订阅 PropertyChanged 事件。如果您将在数据模型上使用继承,那么所有数据模型都必须是可序列化的。在我的场景中,我的数据模型有两个基类:一个用于数据传输,另一个不用于数据传输。