在这种情况下使用DTO的正确方法是什么?

时间:2010-08-08 01:08:44

标签: asp.net-mvc asp.net-mvc-2 domain-driven-design dto

我有以下域类:

public class Product
{
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
    public virtual IList<Product> RelatedProducts { get; set; }
}

我有以下DTO课程:

public class ProductDTO
{
    public ProductDTO(Product product)
    {
        Id = product.Id;
        Name = product.Name;
    }

    public Guid Id { get; private set; }
    public string Name { get; private set; }
}

我的服务中有以下方法:

public ProductDTO GetBySlug(string slug)
{
    Product product = productRepository.GetBySlug(slug);
    return (product != null) ? new ProductDTO(product) : null;
}

我的控制器中有以下操作:

public ActionResult Details(string slug)
{
    ProductDTO viewModel = productService.GetBySlug(slug);
    return View("Details", viewModel);
}

在阅读了一下后,我的理解是使用DTO作为视图模型是可以的,因为当前场景简单直接。当我想要返回的数据变得有点复杂时,我的困惑就出现了。我们假设我也想将相关产品列表返回给视图。我在哪里添加这个列表?

我读到DTO是您的域实体的扁平版本,用于传输数据。这是否意味着不应允许在DTO内部包含相关产品的通用列表?到目前为止我收到的答案表明了这一点。然后,我如何将相关产品送到控制器?

一个选项是:

我不会在服务中返回ProductDTO,而是创建一个新类,该类包含ProductDTO和相关产品的ProductDTO类型列表,并从服务中返回。在控制器中,我会将新类传递给视图,或创建一个单独的ProductViewModel,它包含ProductDTO和相关产品的ProductDTO类型的List,填充它并将其传递给视图。

这是好主意还是坏主意?为什么呢?

由于

1 个答案:

答案 0 :(得分:2)

我根本不会将列表放在DTO中,因为它自然不属于那里。我也不确定你对'包装类'的意思。您只需要一个产品列表,并且在服务上使用另一个返回此列表的方法是完全可以的。

因此,您的服务中会有类似的内容:

public IList<ProductDTO> GetRelatedProducts(ProductDTO productDTO)
{
    ...

viewmodel(上面称为 service 的东西)背后最重要的想法是它介于UI和业务模型之间。换句话说:它以与UI相关的方式编排和聚合业务模型。如果用户界面想要在某个时刻获得相关产品的列表,那么该服务必须提供它。这真的很简单,而且商业模式本身是否也有这个概念与此完全无关。

HTH! 托马斯

P.S。 如果您的DTO变得更大并且列表更长,您可以考虑引入另一个(简化的)DTO,其中只包含名称和某种标识符,以减少您必须从存储库中检索的不必要数据的数量。