1

我正在尝试将它们组合在一起,为现有应用程序构建一个新架构。现有应用程序有很多业务逻辑,所以我认为 Onion 架构(或类似的东西 - 分层、解耦)可能是正确的解决方案 - http://jeffreypalermo.com/blog/the-onion-architecture-part-1 /

我看到的所有示例都在基础设施层(或 DAL,或任何实际连接到数据库的层)中使用 Repo/UoW(顶部或 ORM)模式。但我不确定在我的情况下 Repo/UoW(在 EF 之上)是否必要,因为:

  • EF6 可以在没有 Repo 模式的情况下很好地进行单元测试,并像这样实现有界 DbContexts - http://msdn.microsoft.com/en-us/library/dn314429.aspx

  • 大多数 Generic Repo 示例倾向于使用泄漏抽象,因为它们公开了接受 LINQ 查询的方法(如 Expression> query)

  • 非泛型 Repos 往往会导致大量代码

所以这里有几个问题:

1)大多数示例首先使用EF代码,核心层使用POCO对象,但我必须先使用数据库并生成模型。我可以在 Core 中使用 EF 生成的 .edmx 模型,还是这会对数据访问造成不必要的耦合?有没有办法从 EF 生成的数据访问代码(context.tt 文件等)中拆分 EF 生成的类(带有表字段的 .cs 文件)?

2)我打算像这样实现服务层(有界的 DbContext 接口作为依赖项传递)

public class OrderService(IMyDbContext) { ... } 

这意味着,将有 DbContext 与 DbSet 的包装器接口,而不是存储库接口。可以使用模拟 IMyDbContext 和模拟 IDataSet 来完成单元测试。这不是打败了抽象数据库的整个概念吗?在我看来,这对于单元测试来说已经足够了,但是从架构的角度来看这可以吗?我是否错过了 Repo/UoW(在 EF 之上)模式提供的一些很棒的功能?

3)似乎存储库的一种替代方案(虽然不是很受欢迎)是查询对象: http ://www.wekeroad.com/2014/03/04/repositories-and-unitofwork-are-not-a-good-idea /

http://lostechies.com/jimmybogard/2012/10/08/favor-query-objects-over-repositories/

但我还没有真正找到 Onion + Query Objects 的任何示例。这可能是 Repository 接口层的合理选择吗?将查询接口放在那里,而将查询实现放在接口(数据访问)层?我应该将所有数据访问逻辑放在 QueryObjects 中吗?如果我直接在 Coltroller/Service 层中使用 DbContext.Where 查询,这是否会在数据访问和业务逻辑之间产生不必要的耦合?

4

1 回答 1

3

@andree

我有一些评论可能会添加到这个讨论中。我很欣赏这是一个较旧的线程,但我认为讨论仍然很有价值。

首先,我现在建议不要使用 EDMX 文件,因为未来对 EF7 的所有讨论似乎都表明 EDMX 将被删除。相反,从 EF6.1 开始,您现在可以从现有数据库生成“代码优先”样式配置。

“代码优先”可能应该重命名为“流利配置”

大多数 Generic Repo 示例倾向于使用泄漏抽象,因为它们公开了接受 LINQ >查询(如 Expression> 查询)的方法

非泛型 Repos 往往会导致大量代码

我通常发现有点“泄漏”可能很有用。我们使用共享 IQueryable 的存储库,以便轻松编写快速查询 - 但通常使用的任何内容都会正确移动到存储库中。显然,这会使持久层更难换成其他无法提供 IQueryable 的东西,但实际上这从未发生在我身上。

我对“非通用存储库往往会导致大量代码”问题的处理方法是使用带有 .tt 模板的代码生成。- tt 模板生成一堆部分存储库实现和接口。- 然后,在您自己的部分文件中添加您自己的方法。

请看一下这个库:
http
://www.sswdataonion.com (免责声明:我是这个的开发者之一)
它包含用于生成存储库和工作单元模式的 tt 模板。

就个人而言,如果我要编写一个真正不可知的“无泄漏”服务层,我可能会将其编写为存储库/工作单元模式之上的一个层。

于 2014-11-12T00:07:57.700 回答