代码之家  ›  专栏  ›  技术社区  ›  M. Koch

API和应用层之间的合同应该放在哪个层/项目中?

  •  0
  • M. Koch  · 技术社区  · 2 年前

    环境:
    我正在开发一个系统,该系统是用ASP.NET Core 7构建的模块化整体。作为第一步,有界上下文之间的通信由公开的命令/查询来处理。

    问题:
    我想知道在哪个项目中把合同放在API和应用层之间,这样API层就不能访问除了合同之外的任何东西。

    想法:

    在依赖反转的直接应用中,摘要归上层/策略层所有。该体系结构将较高的/策略组件和定义较低服务的抽象组合在同一个包中。较低级别的层是通过继承/实现这些抽象类或接口来创建的 wikipedia referencing Robert C. Martin: Agile Software Development

    这将导致以下图表(为了简单起见,省略了基础结构层):

    Contract in API layer

    我不明白为什么合同应该与API层相关联。不同的API技术(REST、GraphQL、gRPC)可以并行提供,并且需要访问相同的接口/契约。

    Steven van Deursen在他的《依赖注入》一书中写道

    这种依赖性将使得不可能替换UI。

    它还将使应用程序层依赖于UI层。如果调用另一个有界上下文的服务,则调用方需要对另一个API层的依赖。这一切对我来说毫无意义。

    我看到的大多数例子都将合同放在了应用层:

    enter image description here

    这允许不同的API层同时访问所提供的命令/查询或服务。但这也允许API层访问应用程序层,并且由于C#中项目依赖性的默认传递性,甚至是域层。它可以绕过应用层,直接访问域层。

    我看到了两个防止访问应用程序内部的选项:当使用MediatR时,可以将处理程序类设置为内部,而处理程序是公共的。当使用接口时,应用层中的实现可以是内部的,并且只向DI容器公开 [InternalsVisibleToAttribute] 。域类和服务也需要是内部的,并且域层必须使用 [InteralsVisibleToAttribute] .基础设施层,虽然这里没有涉及,但也需要进行协调。

    由于所有这些都很麻烦,我认为最好的解决方案是将合同放在另一层。

    enter image description here

    应用层只能访问接口,而不能访问其他接口。在其他有界上下文中调用服务只需要依赖于契约。

    应用程序层和域层中的类甚至可以是公共的,因为它们不能再从API层直接访问了。

    我看到的示例中没有一个使用单独的契约层或阻止API层访问应用程序层,这可能是为了简单起见。防止访问较低级别的概念经常被讨论,但没有解释它是如何在.NET中实现的 package protected 可以使用,但是在.NET中如何处理?常见的做法是什么?为什么?

    0 回复  |  直到 2 年前