【发布时间】:2014-01-04 04:37:16
【问题描述】:
1) 在大多数情况下,每个Aggregate Root 都应该定义自己的事务边界,在这种情况下,我们不需要在Domain Layer 中公开IUnitOfWork 接口。
a) 我认为在这种情况下,一个不错的选择是repository(由aggregate 使用以强制在其中应用invariants)包含它自己的UoW 实例(如果使用EF,那么这个UoW 实例可能只是DbContext 类型)?
2)
a) 但是如果出于某种原因transaction 跨越多个aggregates(因此需要一次更改多个aggregate),那么Domain Layer 不会也需要包含IUnitOfWork 接口?
b) 在Domain Layer 中暴露IUnitOfWork 接口不会违反持久性无知规则?
c) 如果 b) 是肯定的,那么暴露IUnitOfWork 是否会破坏拥有repositories 的目的?
回复 Alexey Raga:
1)
I would advice against exposing repositories to aggregates. Repositories are there to give you aggregates, that's it.
a) 虽然我认为大多数 ddd 架构师在将 repos 暴露给聚合时没有问题(我只是问,因为我阅读了几篇关于 repos 和 DDD 的文章,我得到的印象是作者不是反对将存储库暴露给聚合 - 但现在我不再那么确定了)?
b) 所以您也反对将存储库暴露给域服务?
c) 从您的回答来看,我猜您认为将IUnitOfWork 公开为违反 PI?
2)Note that although my command handler (app service in a way)...
您通常将命令处理程序实现为应用服务吗?
3)
public void Handle(ApproveOrderCommand command)
{
var order = Repository.Get(command.OrderId);
property.Approve(command.Comment, ServiceRequiredForOrderApproval);
Repository.Save(order);
}
property.Approve(...) 是不是一个错字,而你的意思是 order.Approve(...)?
提前感谢
【问题讨论】:
-
将 IUnitOfWork 接口作为域的一部分不一定是坏事,就像将存储库接口作为域的一部分也不是坏事一样。只要它们与您的实现完全分开。
-
@stephenl:存储库的目的是抽象出持久性。但是 IUnitOfWork 接口本身不是一个持久性细节,因此通过在域层中引入它,我们将持久性细节泄漏到域层中吗?
-
该接口实际上并没有实现任何东西,因此将其保留在域中是可以的。该接口的实现可能会有所不同,具体取决于您使用的后端存储,因此应该在您的域之外。
-
并非如此。对您的问题的一些回答已经比我更好地回答了这个问题。另一方面,鉴于当今大多数 ORM 已经为您实施变更跟踪,我想知道是否甚至需要 IUoW。如果您删除实现更改跟踪的方法,您只是真正提交或回滚事务,这不一定需要作为单独的模式。还是这样?
-
碰巧Jimmy Bogard 刚刚写了一篇关于这个的博客。见lostechies.com/jimmybogard/2013/12/20/…
标签: domain-driven-design unit-of-work persistence-ignorance