干净的架构和项目之间的循环引用问题

问题描述 投票:0回答:1

我在使用 Clean Architecture 实现一个简单的测试应用程序时遇到了麻烦。

描述测试应用,它是一个销售系统的模拟,用例单一,分为3个包(DLL,用C#制作):

  1. 销售.业务
  2. 销售.适配器
  3. 销售.基础设施

Sales.Business包(黄色和粉色圆圈)中,我们将有:

  • 实体层(关键的业务规则,Bob 叔叔的图表的中心所在),我们将拥有“订单”实体;
  • 用例层,我们将只有一个用例,称为“StartOrder”(或“StartOrderUseCase”、“StartOrderInteractor”,根据需要)。

Sales.Adapters包(绿色圆圈)中,我们将有:

  • 存储库接口;
  • 控制器;
  • 和其他无关紧要的事情……

Sales.Infrastructure包(蓝色圆圈)中,我们将有:

  • 存储库的实施;
  • 和其他无关紧要的事情……

这就是问题开始的地方。

“StartOrder”用例需要访问 OrderRepository 来保存开始的订单。

因为这会违反 Clean Architecture 依赖规则(高层元素访问低层元素),这种访问是通过使用 IPedidoRepository 接口的依赖倒置来完成的。

所以我们有以下参考资料:

StartOrderUseCase --> IPedidoRepository

IPedidoRepository 接口是这样的:

namespace Sales.Adapters;

public interface IOrderRepository
{
...
int SaveOrder(Order order);
...
}

注意接口引用了域实体“Order”(从依赖规则的角度来看这是可以接受的),但这会在项目中造成循环引用问题,因为我们有:

Sales.Business references Sales.Adapters

我们有:

Sales.Adapters references Sales.Business

如果我用这样的 OrderDTO 替换此接口中的 Order 类...

namespace Sales.Adapters;

public interface IOrderRepository
{
...
int SaveOrder(OrderDTO order);
...
}

...问题是一样的,因为 DTO 需要在 Sales.Adapters 包和 Sales.Business 包中使用。无论我把这个 OrderDTO 放在哪里,总会有一个循环引用。

有谁知道如何解决这个问题?

c# repository-pattern circular-dependency clean-architecture circular-reference
1个回答
0
投票

当您需要组合类/接口时,任何 C#“体系结构”都会出现问题,因此常见问题如下所示:

C 
| \
A  B

假设您希望您的代码更改尽可能少,所以如果创建了库 - 您想要开发一次并只应用小错误修复。所以在我们的例子中,A 和 B 现在被锁定以进行修改。我们创建新类型 C 的唯一方法是创建单独的库来保存 C.

总而言之,生产中的这个“问题”是通过以下方式解决的:

  1. 对于与其他系统(SQL、RabbitMQ、Kafka、elastic、日志、DI、通用类等)的集成类(我们示例中的 A、B),有时它被称为 DALData Access Layer library 但对我来说它只是包装器库)-创建一个库,将没有任何业务逻辑的适配器放在那里,也将一些请求/响应 DTO 放在那里,不需要将它们分开,您正在抽象出您的依赖性,也就是创建您自己的协议来与那些系统以防它们以后会改变。
  2. 对于聚合类(在我们的例子中是 C)创建一个垃圾库 (通常称为 BL 又名 业务层库) 您的整个应用程序类工作量。这是最 膨胀的库链接所有适配器并创建聚合 他们中的。随意在这里放任何你喜欢的东西,只是尝试抽象出任何外部依赖。设计模式应该在这里积极应用。
  3. 对于端点(输出,将在单个业务应用程序中链接在一起)创建单独的库(UI、Web、控制台、 等)它将所有 BL 类链接到您的视图或 API 端点。这里除了链接/配置什么都没有。在这里随意阅读设置并配置 DI/IoC 或任何其他与环境的交互是合适的,但不要将业务逻辑放在这里。

附言 我还没有找到这种方法不起作用的地方。到目前为止,我处理过的所有项目都没有崩溃,通常都是这样拆分的。

PS 2 不要试图将业务层拆分成多个库,否则你会遇到同样的问题,以后更难解决。

© www.soinside.com 2019 - 2024. All rights reserved.