两个.NET程序集之间的循环引用

9

我有两个程序集A和B。

A已经引用了B,必须保持这种方式。现在我对B进行了一些更改,需要引用A,因此出现了循环引用问题。

一些详细信息:

A拥有一些属性网格,对话框需要托管在其中。为了避免循环引用问题,我尝试定义接口到第三个程序集中的网格,在A和B都引用该接口,使B只引用这些接口。

我面临的两个问题:

  1. 网格中有太多自定义数据类型(特指属性),已经在A中定义,我不得不为每一个类型定义一个接口。

  2. 我看到通过函数参数的示例可以解决这个问题,例如通过传入的接口调用目标函数。但是考虑以下代码,我无法实例化ICustomPropertyGridWrapper...

    object = new CustomPropertyGridWrapper(...)
    m_property.SelectedObject = object;


B是否需要A的类,还是A更像是利用B中类型的默认使用场景?如果它们紧密耦合,我认为没有理由将它们保留在单独的程序集中。 - Mark H
5个回答

5
这是C#语言设计的一个问题。在C/C++中,您只需使用头文件定义编译单元的接口并解决依赖项。
在C#中没有头文件。您有三个选项:
1.合并程序集(增加编译时间,如果程序集在功能上无关,则可能没有意义)。即使程序集在逻辑上应该是分开的,C#通常也会强制执行此操作。
2.依赖注入
3.创建一个第三方程序集,其中包含模块引用的接口。这通过C#语言机制(接口)实现了依赖注入,而不是自己编写;但本质上是相同的。
通常情况下,选项3是在C#中处理这些情况的方式,但它不像C/C++中的解决方案那样优雅。对于大型代码库,您必须从一开始就考虑到这一点。

我不明白依赖注入在这里如何有帮助。你仍然有两个程序集彼此都需要相互引用。 - Vaccano
C#的指针限制很好。如果是这样,那么Java也适用。不清楚DI如何帮助。需要一个例子来说明。 - liang

4
听起来你似乎在试图通过接口自杀。并不是所有的东西都必须通过接口暴露出来。
一个简单的解决方案是要么合并程序集,要么将常见控件和数据类型移动到第三个程序集中。只有当你想要一种一致的合同方式来访问或处理事物,并且你想要隐藏实际的实现时,才需要使用接口。

1

对于问题1,除了合并两个项目或进行一些代码生成外,实际上没有其他解决方案。

对于第二个问题,您可以通过实现工厂设计模式来解决。


0

重构你的代码或合并程序集 = 不要使用循环引用。这是非常糟糕设计的症状。


3
考虑到你对设计几乎一无所知,而且没有给出任何实质性的建议,对设计进行苛刻的评价并不是很有帮助。我认为你需要提供更具建设性的反馈。 - Kobi
我不知道,但如果你查看其他答案,它们都在描述相同的解决方案 - 重构或合并。所以这已经足够有帮助了。 - Ladislav Mrnka
4
这只是一个糟糕设计的症状。如果有正当理由,好的设计可以表现出糟糕设计的症状,但好的设计师仍会关注这些症状,并确保它们真正合理,并在事物发生变化时仍然合理。 - Jon Hanna
1
这个答案并不苛刻。拥有相互引用的两个程序集,至少在使用时很麻烦。 - Brian Gideon
不要太确定什么是尴尬或糟糕的设计。假设您有一个使用IL编写的实用程序程序集U,并从程序集A引用它,现在您想在U中编写一个小实用方法,该方法必须了解A中的元数据标记。考虑到在.NET Core中没有卸载动态程序集的能力,您该怎么办? - TakeMeAsAGuest

0
如果B现在依赖于A的一些位,你可能应该将这些位重构成一个新的程序集C,由A和B引用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接