是否将我的DTO暴露给被认为不正确的视图?

时间:2011-09-26 10:47:05

标签: c# wpf silverlight mvvm

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

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

 <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>

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

 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映射到视图模型..

3 个答案:

答案 0 :(得分:5)

如果您不需要“塑造”您的DTO以绑定您的视图,那么将DTO直接暴露给您的视图绝对没有错。如果需要,您可以随时在某个时间点引入视图模型。

您还可以使用mini-ViewModel(I describe on my blog)之类的模式添加本地化的View Models来塑造模型的各个部分。

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

KISS - 保持简单!

答案 1 :(得分:5)

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

答案 2 :(得分:2)

从技术上讲,两种方式都是可能的,但是DTO通常不用于查看,因此可能不会触发任何更改通知事件。您必须在DTO中编写代码或冒可能的UI同步问题。我建议不要以这种方式“丰富”你的DTO。

从架构的角度来看,DTO对象应该是便宜且小的对象。它们不需要花费很多精力来实例化或销毁,你不应该把它们传递到你的调用堆栈很远的地方,更不用说让它们长时间保留在内存中了。一般来说,它们意味着是数据封装,它们的目的只是将数据从A带到B.另一方面,ViewModels具有行为并实现更丰富的接口。他们与DTO的唯一共同点是它们也有数据属性。

因此,在您的情况下,我建议不要将DTO作为私有成员保留在视图模型中,而是在检索DTO时设置视图模型属性,然后再次忘记DTO。作为一般建议,不要让您的DTO的生命周期延长到服务电话的方法之后。