在C#中控制传递依赖项

6

我正在使用C#编写支持库,并将其放置在本地NuGet存储库中,该存储库位于我的文件系统中。我注意到,每当我在其中一个库中添加NuGet依赖项,然后在我的某个项目中引用该库时,该项目会自动获得我库中所有NuGet依赖项的可见性。

这并不总是想要的,因为我的库中的名称可能与它们的依赖项中的名称冲突。有没有方法可以隐藏已引用库的依赖项?

举例:我正在开发一个名为foo()的函数,在我的库Lib中引用了一个NuGet依赖项Dep,该依赖项也包含一个foo()函数。现在,如果我将Lib引用到一个名为Proj的项目中,默认情况下会发生的是Proj会同时看到LibDep,并且可以从其中任意一个使用foo()函数。首选的行为是Proj只能看到Lib.foo()

更新

也许这可以作为依赖问题的例子:我在一个项目中导入了iTextSharp和BouncyCastle,这些代码行会产生编译错误:

Org.BouncyCastle.X509.X509CertificateParser cp;
Org.BouncyCastle.X509.X509Certificate[] chain;

文章称,iTextSharp和BouncyCastle中都包含X509CertificateParserX509Certificate的完全限定名称,这意味着iTextSharp引用了BouncyCastle,并且对于反过来引用iTextSharp的任何人都是可见的,即使它在Visual Studio的“引用”下拉菜单中未列出。


1
我的库中的名称可能会与它们的依赖项中的名称发生冲突 - 即使是通过命名空间完全限定的情况下?你能给出一个具体的例子来说明你想避免什么吗? - Jon Skeet
1
不是的,因为通常很清楚你要调用哪个 foo(),因为它会带有实例或类型名称的前缀。你能给出一个完整、具体的例子,说明什么情况下会真正令人困惑吗? - Jon Skeet
我认为你要找的关键字是“global”。参考:https://dev59.com/iWUp5IYBdhLWcg3w1aB7#15022530。虽然我建议使用命名空间来区分不同的类。 - mbshambharkar
1
我和Jon一样,不理解这个问题。在C#中,方法调用始终由接收器明确或隐式限定,该接收器是标识类型的表达式或计算为该类型实例的表达式。如何可能有一个模棱两可的未限定调用?请给我们展示一个例子,以便我们可以弄清楚你在这里说什么。 - Eric Lippert
也许你是对的:总有命名空间来消除歧义。但我不相信在C#中没有隐藏递归依赖的方法... - Luca L.
显示剩余4条评论
1个回答

3
也许这可以作为依赖问题的示例:我在一个项目中导入了iTextSharp和BouncyCastle,但以下代码行会导致编译错误:
Org.BouncyCastle.X509.X509CertificateParser cp;

它说iTextSharp和BouncyCastle都包含X509CertificateParser和X509Certificate的完全限定名称,这意味着iTextSharp引用了BouncyCastle,并且对任何引用iTextSharp的人都可见,即使在Visual Studio的引用下拉列表中没有列出它。
从iTextSharp的源代码来看,作者似乎只是将BouncyCastle代码未经修改地复制粘贴到其项目中,而不是依赖于该程序集。这是一种不好的做法,因为它会导致您现在遇到的问题。
如果您不幸需要使用两个库,其中一个库已经精确复制了另一个库,则正如您所发现的那样,编译器不知道您的完全限定名称指的是哪个库,因此您会收到歧义错误。
解决此问题的最佳方法是不要使用已将其他库复制粘贴到其中的库。但如果这不可能,那么一种方法可以消除歧义,幸运的是,Jon在11年前回答了如何这样做的问题:

Visual Studio 8中程序集引用的别名属性有何用处?

很遗憾,我现在无法将此关闭为重复项,但也许其他人可以这样做。


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