Domain driven design 如何在DDD中执行此操作而不从域实体引用存储库?

Domain driven design 如何在DDD中执行此操作而不从域实体引用存储库?,domain-driven-design,ddd-repositories,Domain Driven Design,Ddd Repositories,我正在努力寻找合适的设计,以避免从实体引用存储库。。。假设我有经典的Customer和Order类,如下所示: public class Customer { ... public IEnumerable<Order> Orders { get; set; } } public class Order { ... public Customer Customer { get; set; } public IEnumerable<Orde

我正在努力寻找合适的设计,以避免从实体引用存储库。。。假设我有经典的
Customer
Order
类,如下所示:

public class Customer {
    ...
    public IEnumerable<Order> Orders { get; set; }
}

public class Order {
    ...
    public Customer Customer { get; set; }
    public IEnumerable<OrderItem> OrderItems { get; set; }

    public void Submit() {
       ...
    }
}

public class OrderItem {
    public Product Product { get; set; }
    public decimal SellingPrice { get; set; }
}
但这将加载整个订单列表,而我只需要最后一个

我想做的事情更像这样:

public void Submit() {
    Order lastOrder = _orderRepository.GetLastOrderFor(Customer);
    CalculatePrice(lastOrder);

但是我知道在域中引用
OrderRepository
是不好的DDD。那么,我该怎么办?我是否必须将Submit()放在域之外的其他位置?如果是,你建议去哪里?

你有两种选择:

创建域服务并从中向存储库添加依赖项:

public class MyPricingStrategy : IPricingStrategy
{
  public MyPricingStrategy(IOrderRepository repository)
  { ... }
}
通过这种方式,您将创建域服务引用存储库,这不是一个很坏的主意

另一种选择是使定价策略成为域对象,应用程序层从存储库传递所需数据:

public class LastOrderPricingStrategy
{
  public LastOrderPricingStrategy(Order lastOrder)
  { ... }
}
在应用层

var lastOrder = orderRepository.GetLastOrder(currentCustomer);
var pricingStrategy = new LastOrderPricingStrategy(lastOrder);

Customer对象可以具有LastOrder属性:

public class Customer {
    ...
    public IEnumerable<Order> Orders { get; set; }
    public Order LastOrder { get; set; }
}

它不需要加载任何东西,因为您需要的订单将在那里。我经常使用只在集合中加载我需要的对象的模式。

如果这是一个适用于所有购买的稳定业务规则,您可以将命令更改为Submit(Order mostRecent)。或者,如果我将定价算法外部化,您也可以将定价算法外部化到另一个类,并将其传递到命令Submit(IPriceCalculator calc)中,IPriceCalculator实现在哪里?这对我来说真的很像域逻辑,不是吗?它只是一个域服务,所以它属于你的域包。好的,谢谢你的解释。因此,我认为在域实体中引用存储库是一种糟糕的设计是正确的,但在域服务中引用存储库是可以的。正确。当特定的行为/流程在现有类中“不适合”时,就需要域服务。你可以把它穿进去,但是你也会注意到内聚和耦合的增加/减少。你是说,如果我访问除上一个订单以外的任何东西,我只会急切地加载上一个订单,然后懒洋洋地加载所有订单?我该怎么做?!我以为加载父对象时,急于加载就是加载所有子对象……这让我起初感到困惑,因为它从来没有出现过,我想知道为什么它从来没有出现过。我从来没有急切地加载一个对象,然后需要其他对象。但很明显:如果我需要所有的对象,我会急切地将它们全部加载!如果您需要,您不会只加载一个对象。您建议的方法的问题是,如果客户有5000个订单,我们会加载所有订单,甚至认为我们实际上只使用最后一个(在此价格计算场景中)。这是一个不必要的性能打击…我一点也不建议。我想说的是,如果你只打算使用一个订单,那么只加载那一个订单。如果要使用所有订单,请加载所有订单。
public class Customer {
    ...
    public IEnumerable<Order> Orders { get; set; }
    public Order LastOrder { get; set; }
}
public void Submit() {
    Order lastOrder = this.Customer.Orders.LastOrDefault();
    CalculatePrice(lastOrder);