将我的DTO暴露在被认为不正确的视图中

本文关键字:不正确 视图 被认为 我的 DTO 暴露 | 更新日期: 2023-09-27 18:09:44

这个问题在过去的几周或几个月里一直萦绕在我的脑海中,我真的不知道什么是最好的解决方案。

使用MVVM模式,我们使用视图模型向视图公开数据。例如,如果我想向用户显示产品的详细信息,我将在视图模型中创建某些特性并填充它们。然后通过绑定,视图将能够从这些属性中获取数据。类似这样的东西:

 <StackPanel>
    <TextBlock Text="Prodcut Name:" FontWeight="Bold" />
    <TextBlock Text="{Binding Path=ProductName}" />
    <TextBlock Text="Price:" FontWeight="Bold"/>
    <TextBlock Text="{Binding Path=Price}"/>
    <TextBlock Text="Added Date:"  FontWeight="Bold" />
    <TextBlock Text="{Binding Path=Date}"/>
</StackPanel>

在视图模型中,我将检索要显示的数据。我将像ProductDTO一样获得这些数据,它将在视图中具有所需的属性。

 this.productDTO = getData();

所以我的问题是,我们可以将directy从视图模型绑定到dto吗?视图模型:

    private ProductDTO product;
    public string ProductName
    {
        get { return this.product.Name; }
        set { this.product.Name = value; }
    }
    public string Price
    {
        get { return this.product.Price; }
        set { this.product.Price = value; }
    }

我认为公开DTO不是一件好事。。但是如果它能让我不必将所有属性从DTO映射到视图模型。。

将我的DTO暴露在被认为不正确的视图中

如果您不需要"成形"DTO来绑定视图,那么将DTO直接暴露在视图中绝对没有错。如果需要,您可以随时在将来的某个时刻引入视图模型。

你也可以使用类似迷你视图模型(我在博客上描述过(的模式来添加本地化的视图模型来塑造模型的各个部分。

像您所做的那样,将DTO封装在视图模型中,会添加不会带来任何好处的代码。它增加了代码库的大小和出现错误的风险。

KISS-保持简单!

private ProductDTO product;
public string ProductName
{
    get { return this.product.Name; }
    set { this.product.Name = value; }
}

我能看到的唯一问题是,当dto的Name属性发生更改时,它并没有简单地反映在UI中。所以我更喜欢这个:

public ProductDTO Product {...}
<TextBlock Text="{Binding Path=Product.Name}" />

这当然需要DTO实现INotifyPropertyChanged

从技术上讲,这两种方式都是可能的,但DTO通常不用于查看,因此可能不会触发任何更改通知事件。您必须将其编码到DTO中,否则可能会出现UI同步问题。我建议不要以这种方式"丰富"你的DTO。

从体系结构的角度来看,DTO对象应该是便宜的小对象。它们不需要太多的精力来实例化或销毁,也不应该将它们传递到调用堆栈的很高位置,更不用说让它们在内存中保留很长时间了。一般来说,它们是数据胶囊,目的只是将数据从A带到B。另一方面,ViewModels具有行为并实现更丰富的接口集。它们与DTO唯一的共同点是,它们还具有数据属性。

因此,在您的情况下,我建议不要将DTO作为私有成员保留在视图模型中,而是在检索DTO时设置视图模型属性,然后再次忘记DTO。一般来说,不要让DTO的生存期远远超过服务调用的方法。