使用实体框架和仓储模式的领域驱动设计

3

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

通过观看 Pluralsight 的教程,他们提到了 存储库 并注意到仓库通常包含基本的 CRUD 操作(创建、更新、获取和删除实体)。关于 Entity Framework 没有太多解释。

Entity Framework 6Entity 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 Web API应用) 因此,为了付款,我想我们需要执行以下操作:
  1. 在我们的控制器/服务中获取客户(例如通过id

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

  3. 然后调用dbContext.SaveChanges()方法

  4. DbContext跟踪更改并存储付款 - 太棒了!

我的理解正确吗?
关于服务层:
在这样的Web应用程序中,拥有DDD的服务层是否可行? 我仍然认为将代码保留在控制器中并不一定是正确的选择(即使采用了DDD),只要在WPF应用程序中可能需要部分功能-因此我们可以使用Service Layer实现。 看起来像是最优的方法,对吧?

1
这个问题太宽泛/基于观点,但我认为你走在了正确的道路上。额外的repo不需要,服务层需要,使用EF类对象的DDD:也许可以考虑。 - Gert Arnold
感谢您的快速回复,@GertArnold。但我认为这并不是太宽泛了...Entity Framework和其他框架在不断发展,对于那些使用略有过时的教程开始学习DDD的开发人员来说,越来越容易产生困惑。再次感谢! - Alex Herman
一些教程甚至不便宜,但它们仍然没有涵盖现代软件堆栈中重要的方面 :) - Alex Herman
1
直到像 Ayende Rahien 这样的有影响力的人开始公开批评这种模式,开发者社区才慢慢开始采纳这种“或许我们可以没有它”的想法。而且,就像你说的,使用 EF 这样的 ORM 又多了一层额外的 repo,更加值得怀疑。 - Gert Arnold
2个回答

3

我在想我们是否可以省略创建Repository层?

在我看来,你不能省略Repository层。一般来说,Repository负责保存和重建聚合根,你的领域实体并不是你的数据库实体。EF实体也不是你的领域实体。

在这样一个Web应用程序中,使用DDD是否可以将Service层保留下来?

当然可以保留你的Service层,实际上,在DDD中,你可以称之为应用层,但你需要关注应该包含哪些内容在这个层中。


3

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

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

我的理解正确吗?

在我看来,如果您已经正确实现了工作单元模式(如您在问题中所述的请求会话),那么您的理解是正确的。这就是它应该的工作方式。

在这样一个Web应用程序中,使用DDD是否有服务层是否可以?

在DDD中,您的领域模型包括相关逻辑。但是,总有一些逻辑不属于任何领域模型。这个逻辑通常在服务中使用。因此,是的,您可能仍然需要具有DDD的服务。只是,它将不包含所有逻辑,因为大部分逻辑都在模型中。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接