环境:
我正在开发一个系统,该系统是用ASP.NET Core 7构建的模块化整体。作为第一步,有界上下文之间的通信由公开的命令/查询来处理。
问题:
我想知道在哪个项目中把合同放在API和应用层之间,这样API层就不能访问除了合同之外的任何东西。
想法:
在依赖反转的直接应用中,摘要归上层/策略层所有。该体系结构将较高的/策略组件和定义较低服务的抽象组合在同一个包中。较低级别的层是通过继承/实现这些抽象类或接口来创建的
wikipedia referencing Robert C. Martin: Agile Software Development
这将导致以下图表(为了简单起见,省略了基础结构层):
我不明白为什么合同应该与API层相关联。不同的API技术(REST、GraphQL、gRPC)可以并行提供,并且需要访问相同的接口/契约。
Steven van Deursen在他的《依赖注入》一书中写道
这种依赖性将使得不可能替换UI。
它还将使应用程序层依赖于UI层。如果调用另一个有界上下文的服务,则调用方需要对另一个API层的依赖。这一切对我来说毫无意义。
我看到的大多数例子都将合同放在了应用层:
这允许不同的API层同时访问所提供的命令/查询或服务。但这也允许API层访问应用程序层,并且由于C#中项目依赖性的默认传递性,甚至是域层。它可以绕过应用层,直接访问域层。
我看到了两个防止访问应用程序内部的选项:当使用MediatR时,可以将处理程序类设置为内部,而处理程序是公共的。当使用接口时,应用层中的实现可以是内部的,并且只向DI容器公开
[InternalsVisibleToAttribute]
。域类和服务也需要是内部的,并且域层必须使用
[InteralsVisibleToAttribute]
.基础设施层,虽然这里没有涉及,但也需要进行协调。
由于所有这些都很麻烦,我认为最好的解决方案是将合同放在另一层。
应用层只能访问接口,而不能访问其他接口。在其他有界上下文中调用服务只需要依赖于契约。
应用程序层和域层中的类甚至可以是公共的,因为它们不能再从API层直接访问了。
我看到的示例中没有一个使用单独的契约层或阻止API层访问应用程序层,这可能是为了简单起见。防止访问较低级别的概念经常被讨论,但没有解释它是如何在.NET中实现的
package protected
可以使用,但是在.NET中如何处理?常见的做法是什么?为什么?