【问题标题】:Dto and domain entities. Did I create my dto correctly?Dto 和域实体。我是否正确创建了我的 dto?
【发布时间】:2010-08-09 07:57:22
【问题描述】:

我有以下域实体:

public class CartItem
{
    public virtual Guid Id { get; set; }
    public virtual Guid SessionId  { get; set; }
    public virtual int Quantity  { get; set; }
    public virtual Product Product  { get; set; }
}

我有以下 DTO:

public class CartItemDTO
{
    public CartItemDTO(CartItem cartItem)
    {
        Id = cartItem.Id;
        Quantity = cartItem.Quantity;
        Name = cartItem.Product.Name;
        Price = cartItem.Product.Price;
    }

    public Guid Id { get; private set; }
    public int Quantity { get; private set; }
    public string Name { get; private set; }
    public decimal Price { get; private set; }
}

当前的工作流程非常简单:我的存储库返回一个 CartItem 类型的 IEnumerable。我的服务将其转换为 dto (CartItemDTO)。然后我的控制器将其传递给视图。到目前为止一切顺利。

现在我想为每个订单项实施总计。我将以下属性添加到 CartItemDTO。

public decimal Total { get; private set; }

然后我将以下代码添加到 CartItemDTO 构造函数。

Total = cartItem.Quantity * cartItem.Product.Price;

我的第一个问题是这是否是最佳实践方法?如果不是,为什么?我应该在其他地方添加 Total 属性吗?如果有,为什么?

我还想为整个购物车实现总计,因此我创建了一个新类(如下)并修改了我的服务以返回它。

public class CartItemResult
{
    public CartItemResult(IEnumerable<CartItemDTO> result)
    {
        CartItems = new List<CartItemDTO>(result);
        Total = result.Sum(total => total.Total);
    }

    public IList<CartItemDTO> CartItems { get; private set; }
    public decimal Total { get; private set; }
}

我现在可以将新类传递给视图,或者创建一个单独的 ViewModel 并将新类的内容传递给 ViewModel 并将其传递给视图。

我的第二个问题是,这种方法是否是最佳实践方法?如果不是,为什么以及我应该采取哪些不同的做法?

【问题讨论】:

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


    【解决方案1】:

    DTO 是用于传输数据的纯类。它不应该包含任何逻辑。您已经添加了域驱动设计标签,所以我认为您想要使用域对象和域服务。您的域对象 (CartItem) 负责计算项目的总数。域对象是数据+业务逻辑和使用该数据的规则。计算总数是业务逻辑。同样对于您的第二部分(CartItemResult),这通常由称为域服务的东西处理。域服务提供的业务逻辑与单个域对象无关,而是与多个域对象一起工作。

    但您还应该考虑项目的复杂性。你真的需要这个吗?不要仅仅因为它们存在就使用它们,总是找到使用它们的理由。 David Neale 提到的方法对于某些应用程序也是正确的。

    最好的问候, 拉迪斯拉夫

    【讨论】:

      【解决方案2】:

      就个人而言,对于数据检索,我建议从存储库中返回 POCO 实体并将其映射到控制器中的 ViewModel (Automapper)。真的不需要中间对象。

      应该在哪里实现Total 属性取决于您的设计。该属性是否在域中用于任何业务逻辑?可以吗?如果不是,那么您可能会认为它只是一个演示问题,并且适用于 ViewModel。

      对于数据更新 - 在您的 UI 中返回类似 CartItemUpdateViewModel 的内容,它映射到控制器中的域实体 CartItemUpdateDetails,然后将其传递给存储库方法。

      就您关于CartItemResult 的问题而言。我个人会将 Total 逻辑放在 ViewModel 中,并从返回 IEnumerable&lt;CartItem&gt; 的存储库方法中将该 ViewModel 填充到控制器中。

      查看 WhoCanHelpMe 项目,了解展示 DDD 的优秀企业应用程序。

      【讨论】:

        猜你喜欢
        • 2021-06-16
        • 1970-01-01
        • 2023-03-04
        • 1970-01-01
        • 2020-11-24
        • 2020-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多