存储库模式和工作单元中的架构问题

Architectural problems in repository pattern and unit of work

我已经使用工作单元实现了存储库模式,但存在一些架构问题。

例如,假设我正在创建一个二手汽车零件在线商店。当我对我的数据库进行操作时,我也需要对来自不同废料场的远程 API 执行操作,例如需要 运行 搜索、可用性更新等...

我决定尝试工作单元和存储库模式

做的事情大多像 Mosh Hamedani 但 asp.net core 2.1 From videos like this one

只要我使用 EF(或其他与 DB 通信的东西),工作单元和存储库就可以正常工作并且有意义,但是如果我要通过不同的方式获取一些数据就没有多大意义网络 apis。 (例如,从不同的 API 获取市场上的汽车列表,其处理和重试相似但不同 - 我正在按键检索同一接口的不同实现)

第一个 我不喜欢这样一个事实,即我在我的工作单元中拥有所有存储库的所有实例,但在大多数情况下只需要一个实例。我知道重用上下文事务而不用我自己包装它是有帮助的,但拥有不必要的实例仍然很愚蠢。

第二 我是否应该在存储库和工作单元内实现远程 api 的检索逻辑和处理,或者放弃工作单元并做其他事情?只保留存储库? (曾经有人提到我不熟悉的门面模式)

我倾向于过度设计事物,现在我很困惑。任何见解都是有帮助的。

存储库模式仅服务于一个目的:从您的应用程序代码中抽象 SQL。工作单元模式的存在只是为了支持和协调多个存储库的事务操作。 EF 和其他 ORM 会为您处理所有这一切。特别是对于 EF,每个 DbSet 是一个存储库,DbContext 是工作单元。当您使用像 EF 这样的 ORM 时,that 是您的数据层,而不是您可能传统上创建的一些自定义 class 库。您绝对 在 EF 之类的东西之上实施 repository/unit 工作模式。

您正在寻找的本质上是一个 API 网关。在微服务架构中,每个服务处理一个离散的功能单元,这意味着使用许多(如果不是全部)这些微服务的横切应用程序将具有大量的依赖性。最典型的方法是创建一个或多个 API 网关,这些网关基本上打包了与所有或特定微服务子集的通信。您的应用程序仅直接与 API 网关对话,并且 API 网关协调与促进应用程序请求所需的所有微服务的通信。这进一步允许您以无缝方式实现消息队列等层。

虽然我同意 Chris Pratt 的回答,但我认为在某些情况下有必要创建存储库,即使您正在使用像 EF 这样的 ORM。我已经详细解释过了 .

关于你的问题,我建议你应该像目前一样继续使用 UoW 和 Repository。如前所述 UoW 不仅仅是交易。如果您正确使用 DbContext.

,EF 会为您完美地实现这一点

关于当前仓库和UoW中涉及其他来源API的问题,应该是分开的。我建议您为使用第三方 API 的复杂性创建单独的包装器。随心所欲地称呼它;存储库或外部 Api 包装器或其他...

我使用了相同的课程并实施了我的工作单元...但后来,我改变了主意并删除了 UoW class。 DbContext 已经在实施 UoW 和存储库模式:From MS Documentation

DbContext Class

Represents a combination of the Unit-Of-Work and Repository patterns and enables you to query a database and group together changes that will then be written back to the store as a unit. DbContext is conceptually similar to ObjectContext.

我仍然添加了自己的存储库。我同意 Chris 的观点,DbSet 是一个存储库,但我可以通过添加我自己的存储库来添加更多专门的方法。

在您链接的视频中,我们通过将所有存储库放入 UoW class 来实现 UoW。在我看来,这个实现可能违反了一些 SOLID 原则:

  1. 感觉违反了Open/Closed原则...因为每次添加新的repository,我们都需要修改UoW class以包含新的Repository。
  2. 感觉违反了接口隔离原则。 ISP 声明不应强迫客户实现他们不使用的接口。 UoW 包含所有存储库的实现......但是消费客户端不需要所有这些实现,客户端可能只需要其中一个。
  3. 感觉我们违反了单一职责原则,因为 UoW 负责这么多的存储库。