gpt4 book ai didi

c# - 具体服务应该依赖于具体的存储库还是接口(interface)?

转载 作者:行者123 更新时间:2023-11-30 22:06:32 25 4
gpt4 key购买 nike

在使用 ASP.net MVC 和 Entity Framework 的同时,我一直在努力实现存储库和服务模式。

我了解存储库模式的目的以及它如何帮助测试并使数据层可互换。然而, Entity Framework 已经是一个存储库/工作单元模式。我见过的存储库模式的每个实现要么剥离 EF 的有用功能,要么实现 IQueryable<T>。让纯粹主义者感到不安的属性(property)。

如果我正在为我的服务层编写接口(interface),那么实现这些服务的具体版本是我不应该直接在服务中使用 Entity Framework 作为我的数据层的原因(而不是将其包装在存储库中/工作模式单元和注入(inject)依赖)?例如:我不能创建一个 IService 吗?接口(interface),然后创建一个具体的 EfService ( Entity Framework )或 NhService (NHibernate 版本)实现?

然后我可以使用我的 IoC 容器来注入(inject)所需的服务和数据上下文。


这是我根据 Sergey 的评论得出的示例:https://github.com/sweeperq/Monona

这就是模式的实现方式吗?

最佳答案

我总是选择存储库接口(interface)。

第一个原因是可测试性 - DbContextDbSet<T>很难 mock 。因此,即使有可能,服务的单元测试也变得非常困难。

第二个原因是 IQueryable<T>被EF曝光。它使数据访问逻辑遍布整个应用程序,这违反了 SRP 并使修复问题变得更加困难。

第三个原因可能不是很重要 - 切换接口(interface)实现的能力 - 不仅是真实对象和模拟,还有不同的数据访问框架。你总是想 - “不,我肯定会坚持使用 EF”。但在现实世界中,由于性能问题和易于开发,我有切换到 Dapper 的经验。并且曾经有过从内存数据存储切换到 EF 的经验。因此,拥有该选项而不是依赖特定于框架的 API 总是很好。

第四个原因是存储库为您提供的很好的特定于域的 API。而不是像 db.Orders.Where(o => o.Category == "Food") 这样的东西你有很好的方法repository.GetOrdersByCategory .

另一个原因是您在一个地方有数据访问逻辑。没有重复。在上面的示例中,您的应用程序中可以有五个地方使用相同的查询按类别过滤订单。使用存储库,您将拥有单一方法,将在五个地方调用。考虑一下如果您的业务规则会发生变化怎么办?例如。您还需要检查类别是否处于事件状态。

另请记住 - 一旦您拥有 UoW 和 Repository 基类和接口(interface),您就可以在不同的项目中重用它们。

关于c# - 具体服务应该依赖于具体的存储库还是接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23571503/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com