19

我正在学习 DDD 开发几天,我开始喜欢它。

我(我想我)了解 DDD 的原理,您的主要关注点是业务对象,您有聚合、聚合根、仅用于聚合根的存储库等。

我正在尝试创建一个简单的项目,将 DDD 开发与 Code First 方法结合起来。

我的问题是:(我正在使用 asp.net MVC)

  1. DDD 业务对象将不同于 Code First 对象?即使它们可能相同,例如我可以拥有一个Product包含所有规则和方法的业务对象,并且我可以拥有一个Product代码优先 (POCO) 对象,它只包含我需要保存在数据库中的属性。

  2. 如果对问题 1 的回答是“真”,那么我如何通知ProductPOCO 对象来自业务对象的属性Product已更改并且我必须更新它?我正在使用“AutoMapper”或类似的东西?如果答案是“不”,我完全迷失了。

你能告诉我如何将这两者放在一起的最简单(CRUD)示例吗?

谢谢

4

5 回答 5

7

更新我不再提倡使用“域对象”,而是提倡使用基于消息传递的域模型。有关示例,请参见此处。

#1的答案是取决于。在任何企业应用程序中,您都会在域中找到 2 个主要类别的东西:

直 CRUD

这里不需要域对象,因为对象的下一个状态不依赖于对象的先前状态。都是数据,没有行为。在这种情况下,可以在任何地方使用相同的类(即 EF POCO):编辑、持久化、显示。

这方面的一个示例是在订单上保存帐单地址:

public class BillingAddress {
  public Guid OrderId;
  public string StreetLine1;
  // etc.
}

另一方面,我们有...

状态机

您需要有单独的对象用于域行为和状态持久性(以及完成工作的存储库)。域对象上的公共接口应该几乎总是所有 void 方法并且没有公共 getter。订单状态就是一个例子:

public class Order { // this is the domain object  
  private Guid _id;
  private Status _status;

  // note the behavior here - we throw an exception if it's not a valid state transition
  public void Cancel() {  
    if (_status == Status.Shipped)
      throw new InvalidOperationException("Can't cancel order after shipping.")
    _status = Status.Cancelled;
  }

  // etc...
}

public class Data.Order { // this is the persistence (EF) class
  public Guid Id;
  public Status Status;
}

public interface IOrderRepository {
  // The implementation of this will:
  // 1. Load the EF class if it exists or new it up with the ID if it doesn't
  // 2. Map the domain class to the EF class
  // 3. Save the EF class to the DbContext.
  void Save(Order order); 
}

#2 的答案是 DbContext 将自动跟踪对 EF 类的更改。

于 2012-12-28T01:58:03.430 回答
2

答案是否定的。EF 代码优先的优点之一是它非常适合 DDD,因为您必须手动创建业务对象,因此请务必使用您的 EF 模型来等效于 DDD 实体和值对象。无需增加额外的复杂性,我认为 DDD 不建议在任何地方这样做。

您甚至可以让您的实体实现 IEntity,并为对象赋值以实现 IValue,此外还可以遵循其他 DDD 模式(即存储库)来与数据库进行实际通信。更多这些想法你可以在 .NET 中找到这个非常好的示例应用程序,即使它不首先使用 EF 代码,它仍然非常有价值:http ://code.google.com/p/ndddsample/

于 2012-11-04T16:26:09.893 回答
2

最近我做了类似的项目。我正在关注本教程:链接 我已经这样做了:我创建了空白解决方案,添加了项目:域、服务和 WebUI。

简单地说,在域中我已经放置了模型(例如,EF 代码的类,方法等)服务用于域与世界(WebUI,MobileUI,其他站点等)使用 asp.net webapi WebUi 实际上是 MVC应用程序(但模型在域中,所以它主要是 VC)

希望我有所帮助

于 2012-11-04T21:51:51.020 回答
1

Pluralsight 课程:企业中的实体框架进入了与 EF Code First 相结合的领域驱动设计的确切场景。

对于第一名,我相信你可以做到这一点。这只是风格问题。对于第 2 点,视频中的讲师通过几种方式来说明这一点。一种方法是在修改值时在客户端设置的每个类上都有一个“状态”属性。然后 DbContext 知道要保留哪些更改。

于 2012-11-04T13:27:47.457 回答
0

关于这个主题的迟到问题。阅读 Josh Kodroff 的回答证实了我对将存储库实施到例如实体框架 DAL 的想法。

您将域对象映射到 EF 持久性对象,并在保存时让 EF 处理它。检索时,您让 EF 从数据库中获取并将其映射到您的域对象(聚合根)并将其添加到您的集合中。

这是存储库实施的正确策略吗?

于 2013-09-13T09:45:56.000 回答