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

发布于 2024-12-06 09:36:18 字数 1098 浏览 1 评论 0原文

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

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

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

 this.productDTO = getData();

所以我的问题是,我们可以直接从视图模型绑定到 dto 吗? View Model:

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

This question has been round my head the last weeks or months, and I don't really know what's the best solution.

With the MVVM patter we use the View Models to expose data to a View.
For example, if I want to show to a user the details of a product I will create certain propeties inside the View Model and populate them. Then through bindings, the view will be able to get the data from those properties. Something like this:

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

In the view model I will retrieve the data that I want to display. I will get this data like a Product DTO, which will have the needed properties in the view.

 this.productDTO = getData();

So my question is, can we bind directy from the view model to the dto?
View Model:

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

I have the idea that exposing the DTO is not a good thing..
but if It will save me from having to map all the properties from the DTO to the view model..

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

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

发布评论

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

评论(3

誰認得朕 2024-12-13 09:36:18

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

您还可以使用迷你 ViewModel 等模式(其中 我在我的博客上描述了)添加本地化视图模型来塑造模型的各个部分。

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

KISS - 保持简单!

If you do not need to 'shape' your DTO in order to bind your view, there is absolutely nothing wrong with exposing your DTO directly to your view. You can always introduce a view model at some point in the future if required.

You can also use patterns like the mini-ViewModel (which I describe on my blog) to add localised View Models to shape parts of your model.

Wrapping your DTO in a view model as you have done, adds code that does not provide any benefit. It increases the size of your code-base and the risk of bugs.

KISS - Keep it simple!

赤濁 2024-12-13 09:36:18
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

private ProductDTO product;

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

the only problem i can see is that, when your Name property of your dto changed its not simply reflected in your UI. so i would prefer this:

public ProductDTO Product {...}

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

this of course requires that your DTO implement INotifyPropertyChanged

梦醒时光 2024-12-13 09:36:18

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

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

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

Technically both ways are possible, however a DTO typically is not meant for viewing and thus will probably not fire any change notification events. You'll have to either code that into your DTO or risk possible UI synchronization issues. I would advise against "enriching" your DTOs in such a way.

From an architecture standpoint DTO object should be cheap and small objects. They don't require a lot of effort to instantiate or destroy and you shouldn't pass them very far up your call stack let alone let them remain in memory for very long. In general they're meant to be data capsules and they're purpose is only to bring the data from A to B. ViewModels on the other hand have behavior and implement a richer set of interfaces. The only thing they have in common with DTOs is that they also have data properties.

So, in your case I'd advise not to keep the DTO in your view model as a private member, but set the view models properties upon retrieving the DTO and then forget about the DTO again. As a general advise, don't let your DTOs lifetime extend very far past the method with the service call.

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