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

发布于 2024-08-31 03:26:53 字数 423 浏览 1 评论 0原文

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

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

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

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

I'm currently working on what will be my first real foray into using MVVM and have been reading various articles on how best to implement it.

My current thoughts are to use my data models effectively as data transfer objects, make them serializable and have them exist on both the client and server sides.
It seems like a logical step given that both object types are really just collections of property getters and setters and another layer in between seems like complete overkill.

Obviously there would be issues with INotifyPropertyChanged not working correctly on the server side as there is no ViewModel to which to communicate, but as long as we are careful about constructing our proper domain model objects from data models in the service layer and not dealing the the data models on the server side I don't think it should be a big issue.

I haven't found too much info about this approach in my reading, so I would like to know if this is a pretty standard thing, is this just assumed to be the de facto way of doing MVVM in a multi-tier environment?
If I've got completely the wrong idea about things then thoughts on other approaches would be appreciated too.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

_失温 2024-09-07 03:26:53

您可以使用任何您觉得舒服的模型,是的,您的所有属性都需要 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:// Fluentviewmodel.codeplex.com/ 查看

You can use whatever model you feel comfortable with, yes all of your properties will need INotifyPropertyChanged behavior. How this will effect the service layer is entirely down to your implementation.

I'm assuming that you ment that you bind to your DTO's in your view?

How I see it is that there is an impedence mismatch between the layers of the application, that is your
Domain Model probably looks simliar to your Relational Model, with subtle but crucial differences. There is also
a mismatch between the Domain Model and your DTO's (objects may be flattened, computed properties, etc, ...). It's tempting to bind directly to the DTO's as they are probably designed to have what you need for the particular operation, however there is also an impedence mismatch between the DTO and what is needed by the view in order to acheive the desiged outcome. This is where the View Model comes in. The view model has responsibility to proxying the DTO properties to the view, it is responsible for letting the view know if there are validation errors, and routes commands to the appropriate handler (Save, Delete, etc, ...).

I tend to set things up in the following way :

// 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()
   {
   }
}

Your EditAddressView would then bind to the EditAddressViewModel. Basically the rule is all of your UI behavior should be expressed in terms of your view model.

Yes that does mean extra work, howerver there are things you can do to simplify things a bit (code generation etc). I'm actually working on a library that aims to simplify whole MVVM process using a fluent api. Check it out at http://fluentviewmodel.codeplex.com/

阳光①夏 2024-09-07 03:26:53

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

I'm no expert on this. I had just the same scenario. I agree with you that that is quite an overkill. I've been using this solution for quite some time now and haven't encountered any issues. The INotifyPropertyChanged isn't a big problem for me since nothing on the server-side will subscribe to the PropertyChanged event. If you will use inheritance on your data models, then all must be serializable. In my scenario, I have two base classes for my data models: one that is used for data transfer, and the other not.

怪异←思 2024-09-07 03:26:53

我决定在我的 ViewModel 上有一个属性“Model”。在模型本身中,我已经实现了 IPropertyNotifyChanged 和 IDataErrorInfo。因此,在我的 ViewModel 中,我跳过了代码将简单地“落入”模型的属性。相反,视图直接绑定到这些属性的模型。

对于更复杂的情况,我必须调整模型中的数据以适应视图,我在 ViewModel 中执行此操作。另外,命令等都在 ViewModel 中。但我不认为 ViewModel 中的样板代码重复模型中已有的相同内容的原因。

I decided to have a property "Model" on my ViewModel. In the model itself I already implement IPropertyNotifyChanged and IDataErrorInfo. In my ViewModel I thus skip properties where the code would simply "fall-through" to the model. Instead, the View binds directly to the model for those properties.

For more complicated cases, where I have to adjust the data in the model to fit the view, I do this in the ViewModel. Also, the commands, etc. are in the ViewModel. But I do not see the reason to have boilerplate code in the ViewModel repeating the same stuff which I already have in the model.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文