EF6和Onion架构 - 数据库优先,没有Repository模式

时间:2014-05-21 07:44:22

标签: entity-framework onion-architecture

我正在尝试将所有内容整合在一起,以便为现有应用程序提供新架构。现有的应用程序有很多业务逻辑,所以我认为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代码和Core层中的POCO对象,但我必须先使用数据库并生成模型。我可以在Core中使用EF生成的.edmx模型,还是会对数据访问进行不必要的耦合?有没有办法从EF生成的数据访问代码(context.tt文件等)中拆分EF生成的类(带有表字段的.cs文件)?

2)我打算像这样实现Service层(将Bounded DbContext接口作为依赖项传递)

public class OrderService(IMyDbContext) { ... } 

这意味着,与DbSets不同的是DbContext包装器接口,而不是存储库接口。单元测试可以使用模拟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/

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

1 个答案:

答案 0 :(得分:3)

@andree

我有一些评论可能会增加这个讨论。我很欣赏这是一个较旧的帖子,但我认为讨论仍然很有价值。

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

"代码优先"应该重命名为"流畅的配置"

  

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

     

非通用Repos往往会导致很多代码

我一般都发现,做一点"泄漏"会很有用。我们使用共享IQueryable的存储库,这样可以很容易地编写快速查询 - 但是经常使用的任何东西都会被正确地移动到存储库中。显然,这会使持久层更难换掉其他不能给你带来智能的东西,但实际上我从来没有这样做过。

我对"非通用Repos的方法倾向于导致大量代码"问题一直是使用.tt模板生成代码。 - tt templates生成一堆部分存储库实现和接口。 - 然后,在您自己的部分文件中添加自己的方法。

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

就个人而言,如果我要写一个真正不可知的"非泄漏"服务层我可能只是将它作为一个层写在存储库/工作单元模式之上。