代码之家  ›  专栏  ›  技术社区  ›  JonC

我应该在mvvm中使用dto作为我的数据模型吗?

  •  11
  • JonC  · 技术社区  · 14 年前

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

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

    显然,如果inotifPropertyChanged不能在服务器端正常工作,则会出现问题,因为没有要与之通信的ViewModel,但是只要我们小心地从服务层的数据模型构造适当的域模型对象,并且不处理数据服务器端的模型我认为这不应该是个大问题。

    我在阅读中并没有发现太多关于这种方法的信息,所以我想知道这是否是一个非常标准的事情,这只是假设这是在多层环境中进行mvvm的实际方法吗? 如果我对事情有完全错误的想法,那么对其他方法的想法也会很感激。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Michael Detras    14 年前

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

        2
  •  5
  •   bobble79    14 年前

    您可以使用您认为合适的任何模型,是的,您的所有属性都需要inotifyproperty更改的行为。这将如何影响服务层完全取决于您的实现。

    我假设你认为你和你的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://fluentviewmodel.codeplex.com/

        3
  •  1
  •   Daniel Rose    14 年前

    我决定在viewmodel上有一个属性“model”。在模型本身中,我已经实现了ipropertynotifychanged和idataerrorinfo。因此,在我的viewmodel中,我跳过了代码只会“通过”到模型的属性。相反,视图直接绑定到这些属性的模型。

    对于更复杂的情况,我必须调整模型中的数据以适应视图,我在view model中这样做。此外,命令等也在viewmodel中。但我不认为有理由在viewmodel中使用样板代码来重复我在模型中已有的东西。