DDD,CQRS,洋葱架构,企业级应用程序的ef核心

时间:2019-09-20 07:50:14

标签: entity-framework domain-driven-design cqrs onion-architecture

最近,我发现以下方法对我从事的许多项目非常有用。 但是,问题是,我读到ef核心DbContext本身就是一个UoW,我不应该创建自己的UoW和存储库。但是在这种情况下,我无法从我的应用程序逻辑层抽象我的持久性层。

TL; DR问题是: 是否可能没有自己的存储库,也没有自己的UoW,而仍然按照DbContext作为UoW遵循上述体系结构?

我的体系结构如下:

第1层(最内部): 聚合,实体,POCO域类,值对象

第2层: 域服务

第3层: 应用程序服务(CQRS命令,查询,处理程序)和存储库接口

4A层 :(持久层) 存储库实现(在此处注入了DbContext) EF核心映射(ORM映射)

4B层: Asp MVC API(在此处注册DI)

API控制器仅通过MediatR发出命令和查询。

上述方法的优点是应用核心(第1、2和3层)完全从持久性中抽象出来。 缺点是您确实必须编写自己的存储库。

这是正确的方法吗?还是我错过了什么?

1 个答案:

答案 0 :(得分:2)

为什么DbContext是工作单元?

DbContext通过一次提交( SaveChanges )捕获您在一次事务中所做的所有更改。

为什么不创建自己的?

理想情况下,您只应通过一个事务提交一个数据存储。如果要在多个事务中保存到多个数据存储中,或者在多个事务中保存到同一数据存储中,那么您将面临数据损坏的可能。如果您正在跨多个数据存储使用分布式事务,那么上帝会帮助您。

SaveChanges应该足够了,那么为什么要创建自己的?

那抽象呢?

如果SaveChanges足够,那么我们如何抽象出对EF的依赖?您可以使用单个方法提交引入 IUnitOfWork 接口,可以通过调用DbContext.SaveChanges来实现该接口。

还有存储库?

我不确定我是否理解不将存储库作为硬性规则。作为抽象化持久层的一部分,使用IRepository这样的层来提供这种分离是有帮助的。也就是说,您不应该为每个表创建一个存储库。每个聚合的存储库更合适。每个存储库将加载整个集合,以确保集合边界内的一致性。

...

通常,如果您不理解该建议背后的原因,我会警告您不要遵循绝对的建议。给您相同的开始信息,您应该能够得出相同的结论。否则,您只是将死记硬背应用于一种无法始终从该方法中受益的模式。