【问题标题】:Cyclic Dependencies循环依赖
【发布时间】:2025-12-18 23:20:02
【问题描述】:

考虑一个使用 WinForms 的基于 MVC 模式的普通客户订单应用程序。 视图部分增长过多(超过 4000 个文件),需要拆分成更小的部分。


对于这个例子,我们将使用 3 个项目作为视图部分:

  • Main - 依赖于其他 2 个项目。用列表实例化表单。
  • 客户 - 有 2 个表格 - 客户列表和客户详细信息。
  • 订单 - 有 2 种表格 - 订单列表和订单详情。

在客户详细信息表单上,还有该客户的订单列表。该列表是从 OrdersController 接收的,因此获取它没有问题。当用户选择一个订单时,列表将获取它的 guid 并将其作为参考传递给 Order Details 表单。

这意味着我们需要在客户项目中引用订单项目。 (1)

此外,在订单详情表单上,还有一个指向下订单的客户的链接。单击后,它应该会打开“客户详细信息”表单。

这意味着我们需要在 Orders 项目中引用 Customers Project。 (2)

从 (1) 和 (2) 开始,我们将在 Orders 和 Customers 项目之间建立循环依赖关系。


如何避免这种情况? 某种插件架构?该项目已经开发完成,最好的解决方案是尽可能少地更改代码。

【问题讨论】:

  • 项目之间如何交互?

标签: c# asp.net-mvc dependencies


【解决方案1】:

将至少一种类型更改为接口。

例如,有一个 ICustomer 接口和一个实现此接口的 Customer 类型。现在将 ICustomer 添加到 orders 项目,并从 customers 项目中设置对 Orders 项目的引用,以便您可以实现接口。 Order 类型现在可以在不知道实际实现的情况下针对 ICustomer 类型工作。

为了更好的解决方案:-) 创建 ICustomer 和 IOrder 接口并将它们添加到第三个库项目。并从其他两个中引用这个项目,并且只使用接口,从不使用实现。

【讨论】:

  • 如何解决:订单需要实例化客户,客户需要实例化订单?
【解决方案2】:

如果它们耦合得那么紧密,也许它们不应该被拆分。

【讨论】:

    【解决方案3】:

    提取接口并将它们放在单独的程序集中。由于您使用的是 MVC 架构,因此应该不难。查看 Microsoft 复合 UI 应用程序块以获取示例和良好做法。

    【讨论】:

      【解决方案4】:

      我认为您的主要问题不是应用程序的架构。您需要了解边界以及如何在它们之间划分功能。像您这样的划分是相当人为的,您尝试根据域对象拆分应用程序。尝试使用用户角色或功能主题来做到这一点,问题可能会消失。

      从技术的角度来看,我不明白为什么你的观点应该意识到彼此的存在——这听起来有点奇怪。您不会拆分数据和业务逻辑,归根结底,GUID 只是一个您可以使用不同方法轻松传递的刺。

      【讨论】: