Entity Framework 和存储库模式的领域驱动设计

Domain-Driven Design with Entity Framework & Repository Pattern

我过去常常处理具有包含所有业务逻辑的 服务层 的简单应用程序。在领域驱动设计中,将业务逻辑保留在丰富的模型中是很常见的。

观看了 Pluralsight 的教程,其中提到了 Repositories,并注意到 repo 通常包含基本的 CRUD 操作(创建、更新、获取和删除实体)。关于 Entity Framework.

没有太多解释

Entity Framework 6 & Entity Framework Core 已经提供 Repository/UoW 开箱即用。 我想知道在这种情况下我们是否可以省略创建存储库层?

所以,我如何想象没有单独的存储库层的应用程序...

我的理解是:

例如,我们有 Customer 模型作为聚合根(富域模型)。该模型具有一对多关系 ICollection<Payment> Payments。另外,根据 DDD - 我们将逻辑保留在模型中 - 所以我们有 MakePayment 方法。

代码如下:

public class Customer
{
    public virtual ICollection<Payment> Payments { get; set; }

    // ... other properties/collections

    public void MakePayment(decimal amount)
    {
        this.Payments.Add(new Payment() { Amount = amount });
    }
}

使用 Entity Framework 我们可以 急切地加载 整棵树,结果 Customer 已经拥有了他们所有的Payments 已映射。

(比如说,我们处理一个 ASP.NET WebAPI 应用程序)

因此,我想,为了付款,我们会执行以下操作:

  1. 在我们的控制器/服务中,我们获取客户(例如通过 id

  2. 然后是代码customer.MakePayment(10);

  3. 之后我们调用dbContext.SaveChanges()方法

  4. DbContext 跟踪更改并存储付款 - Bingo!

我的理解正确吗?


关于服务层:

在这样的 Web 应用程序中使用 DDD 的服务层可以吗?

我仍然认为将代码保留在控制器中不一定是正确的做法(即使使用 DDD)只要例如WPF 应用程序可能需要部分功能 - 因此我们可以将服务层与其一起使用。

似乎是最佳方法,不是吗?

我想知道在这种情况下我们是否可以省略创建存储库层?

在我看来,你不能省略 Repository Layer。通常,Repository 负责 Save and Rebuild Aggregate Root,你的域实体不是你的数据库实体。 EF 实体不是您的域实体。

在这样的 Web 应用程序中使用 DDD 的服务层可以吗?

当然你可以保留你的Service Layer,实际上你可以在DDD中调用它Application Layer,但是你需要注意什么应该包含在这一层中。

I'm wondering if we can omit creating Repository Layer in this case?

如第一段 中所述,请考虑直接使用通用存储库 (DbSet)。避免创建额外的存储库层。

Is my understanding correct?

IMO,如果您正确实施了工作单元(如您在问题中解释的那样,每个请求的会话)模式,那么您的理解是正确的。这就是它应该如何工作。

Would it be okay to have Service Layer with DDD in such a web app?

使用 DDD,您的域模型包含相关逻辑。但是,总有一个逻辑不属于任何领域模型。该逻辑通常在服务中使用。所以是的,您可能仍然需要使用 DDD 的服务。仅此而已,它不会包含您的所有逻辑,因为其中大部分都在模型中。


对于 DDD,请考虑使用 CQRS。使用 CQRS,您可以将对数据存储的读取和写入分开。在这种情况下,存储库是可选的。如上所述,您可以使用 ORM 公开的通用存储库。