阅读Eric Evans的域驱动设计后,我有几个问题。我搜索但没有在哪里我能找到令人满意的答案。如果您有任何人明确了解以下问题,请告诉我。
我的担忧是
存储库用于从DB,Web服务获取已存在的聚合。 如果是,Can Repository也有对该实体的交易呼叫(即转账金额,发送账户明细......等)
实体可以拥有具有业务逻辑的方法,其中它调用基础结构层服务以发送电子邮件..日志等(实体方法调用IS服务直接)。
存储库实现和工厂类将驻留在Infrastrucure层中。这是正确的陈述吗?
UI层(控制器)可以直接调用Repositry方法吗?或者我们应该从应用层调用这些?
我心中还有很多困惑......请指导我...... 书籍我正在使用Eric Evan的域名驱动设计...... 使用C#进行.NET域驱动设计
答案 0 :(得分:13)
关于存储库是应该是只读还是允许事务,存在很多争论。 DDD并未规定任何这些观点。你可以做到这两点。只读存储库的支持者更喜欢所有CUD操作的工作单元。
大多数人(自我包含)认为实体是持久无知的良好做法。稍微扩展该原则将表明它们应该是自包含的并且没有所有基础设施层服务 - 即使是抽象形式。所以我会说对基础结构服务的调用属于在实体上运行的服务类。
Repository实现和Factories(如果有的话)应该驻留在基础架构层中,这听起来是正确的。但是,它们的接口必须位于域层中,以便域服务可以与它们进行交互,而不依赖于基础结构层。
DDD并不真正决定您是否可以跳过图层。在本书的后半部分,Evans谈到了一些关于分层的问题,并在你允许的时候称它为Relaxed Layering,所以我猜他只是把它看作是几个中的一个选项。就个人而言,我更愿意阻止图层跳过,因为如果调用已经通过正确的图层,它会在将来更容易注入某些行为。
答案 1 :(得分:9)
就个人而言,在我最新的DDD项目中,我使用了一个持有NHibernate会话的工作单元。 UoW被注入存储库中,让他们负责添加,删除和查找。
埃文斯已经表示,DDD书中缺少的一个难题是“域名事件”。使用像Udi Dahan's DomainEvents这样的东西会给你一个完全解耦的架构(域对象只会引发一个事件)。就个人而言,我使用Domain Events和StructureMap的修改版本进行布线。它非常适合我的需求。
我建议,根据其他建议,Repository接口是模型的一部分,它们的实现是基础结构的一部分。
是的!我亲自参与了三个DDD Web项目,其中服务和存储库被注入到演示者/控制器(ASP.NET / ASP.NET MVC)中,它在我们的上下文中有很多意义。
答案 2 :(得分:1)
存储库应仅用于定位和保存实体,该层中不应存在任何业务逻辑。例如:
repository.TransferAmount(amount,toAccount); //这很糟糕
实体可以执行诸如发送电子邮件之类的操作,只要它们依赖于您域中定义的抽象。实施应该在您的基础架构层中。
是的,您将存储库实施放在基础架构层中。
UI层(控制器)可以直接调用Repositry方法吗?或者我们应该从应用层调用它们吗?
是的,我试图在大多数情况下遵循这种模式:
[UnitOfWork]
public ActionResult MyControllerAction(int id)
{
var entity = repository.FindById(id);
entity.DoSomeBusinessLogic();
repository.Update(entity);
}