我曾经处理过具有 Service Layer 且包含所有业务逻辑的简单应用程序。在域驱动设计中,通常将业务逻辑保持在丰富的模型中。
观看了Pluralsight的教程,其中提到了存储库,并注意到存储库通常包含基本的CRUD操作(创建,更新,获取和删除实体)。关于实体框架没有太多解释。
实体框架6 和实体框架核心已经提供了现成的 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应用)
因此,我想为了付款,我们执行以下操作:
在我们的控制器/服务中,我们获取了一位客户(例如,通过id
)
然后遵循代码customer.MakePayment(10);
之后,我们调用dbContext.SaveChanges()
方法
DbContext
跟踪更改并存储付款- Bingo!
我的理解正确吗?
关于服务层:
在这样的Web应用程序中具有DDD的服务层可以吗?
我仍然认为将代码保留在控制器中不一定是正确的事情(即使使用DDD),只要例如WPF应用程序可能需要功能的一部分-因此我们可以将其与服务层一起使用。
似乎是最理想的方法,不是吗?
答案 0 :(得分:2)
我想知道在这种情况下是否可以省略创建存储库层吗?
在我看来,您不能省略存储库层。通常,存储库负责聚合根的保存和重建,并且您的域实体不是您的数据库实体。 EF实体不是您的域实体。
在这样的Web应用程序中具有DDD的服务层可以吗?
您当然可以保留您的服务层,实际上,您可以在DDD中将其称为应用层,但是您需要注意该层应包括的内容。< / p>
答案 1 :(得分:1)
我想知道在这种情况下是否可以省略创建存储库层?
如第一段here中所述,请考虑直接使用通用存储库(DbSet
)。避免创建附加的存储库层。
我的理解正确吗?
IMO,如果您已正确实现工作单元(问题中所述的每个请求的会话)模式,则您的理解是正确的。那应该是这样的。
在这样的Web应用程序中具有DDD的服务层可以吗?
使用DDD,您的域模型包括相关的逻辑。但是,总有一种逻辑不属于任何领域模型。该逻辑通常在服务中使用。因此,是的,您可能仍然需要DDD服务。只是,它不会包含您的所有逻辑,因为大多数逻辑都在模型中。
对于DDD,请考虑使用CQRS。使用CQRS,您可以将对数据存储的读取和写入分开。在这种情况下,存储库是可选的。如上所述,您可以使用ORM公开的通用存储库。