C# .NET 中挥之不去的程序集依赖项
Posted
技术标签:
【中文标题】C# .NET 中挥之不去的程序集依赖项【英文标题】:Lingering assembly dependency in C# .NET 【发布时间】:2010-09-05 18:26:30 【问题描述】:我的 C# 项目 - 我们将其称为 SuperUI - 用于使用来自外部程序集的类。现在它没有,但编译器不会让我在没有适当的程序集引用的情况下构建项目。让我详细说明。
这个项目用于抛出和捕获一个自定义异常类 - SuperException
- 它派生自标准 System.Exception 并存在于一个单独的预编译程序集 SuperAssembly.DLL
中,我引用了它。
最终,我认为这是一个毫无意义的练习,并在每种情况下都将所有 SuperExceptions
替换为 System.SuitableStandardException。我删除了对SuperException.DLL
的引用,但现在在尝试编译项目时遇到了以下问题:
“SuperException”类型是在未引用的程序集中定义的。您必须添加对程序集 'SuperException, Version=1.1.0.0 (...)' 的引用
错误引用的源文件似乎不相关;它是在 IDE 中突出显示的项目命名空间。
现在,事情是这样的:
SuperException
的所有用法都已从项目代码中删除。
与另一个在没有引用SuperException.DLL
的情况下编译良好的项目相比,我只引用了一个程序集 - 而that
没有引用我的项目不引用自身的任何内容。虽然这些依赖项中的任何一个都可能抛出 SuperExceptions
,但我只捕获了基本的 Exception 类,无论如何......另一个项目构建得很好!
我已经完成了 Visual Studio 的“清洁解决方案”并多次手动清除所有内容。
包含此引用并不是世界末日,我只是不明白为什么不再需要它。 Nrrgg。欢迎大家指点!
【问题讨论】:
【参考方案1】:这很可能是一个传递引用,其中某些类型的方法调用返回一个 SuperException 装箱(“downcast”)的实例,例如例外,但是通过检查传递包含的代码中的代码,即来自外部方法调用的代码,编译器知道您需要能够在某个时候获得有关该类型的信息。
Resharper 会告诉您在什么情况下需要添加引用,您可以使用 Lütz Roeder 的又名 RedGate 的 Reflector 以两种方式扫描编译后的 IL 以获取对该类型的引用:1) 使用搜索工具, 2) 打开您正在使用的每种公共类型,对于需要“ghost”程序集的那种,它会要求您指定其位置。
当我引用 Castle.Windsor 而不是 Castle.MicroKernel 时,这最常发生在我身上。 :p
【讨论】:
【参考方案2】:-
退出 Visual Studio
删除解决方案目录中的 bin 和 obj 文件夹
重启看看会发生什么
【讨论】:
【参考方案3】:我同意这里的其他 cmets.. 有一个参考,纯文本 somewhere ! 过去我也遇到过类似的问题,在项目文件中搜索什么也没有返回,结果是在搜索中没有自动找到的其他文件中。
我不认为创建一个新项目是这里的解决方案。你需要肯定你的依赖树中的 NONE 引用使用 SuperException.. NONE em>
我从来没有经历过这种情况,以至于我需要从字面上擦除项目,我总是在某处找到参考。确保您正在搜索每个文件。
编辑:
补充一点,如果错误指向的位置看起来是随机的,这通常意味着编译的源代码和源代码文件不匹配。这是一个 ASP.NET 应用程序吗?我以前在 ASP.NET 临时文件夹中的重建中没有替换已编译的 DLL 导致事情发生。调试时很有趣 :)
【讨论】:
【参考方案4】:我认为这不是代码问题。我可以看到正在发生的是,您现有的引用之一可能依赖于您可能在应用程序中创建的类型中的该类型。
如果是这种情况,即使您没有显式使用该类型并且即使其他引用的程序集有自己的引用,您也确实需要该引用。您有时会遇到需要引用您未引用的类型的第 3 方组件的问题。编译器显然在您现有的一个引用程序集中看到了一些东西,并希望您引用依赖项。
【讨论】:
尝试使用反射器在其他引用的程序集中搜索 SuperException 以验证它们没有引用程序集。【参考方案5】:既然是编译器错误,那么项目中一定有引用或使用SuperException的地方。
-
在整个项目或解决方案中查找/替换该类型并删除所有引用(您可能已经这样做了)。
如果您引用任何继承自 SuperException 的类型(即使是在另一个程序集中定义的类型),您需要对定义 SuperException 的程序集的引用。
选择编译器显示错误所在的行并开始跟踪该行上使用的对象的继承树,您可能会通过这种方式找到它的来源。
【讨论】:
【参考方案6】:到目前为止,感谢您的回答。我已经尝试了所有建议(除了一个)都无济于事。
我没有尝试过的建议是创建一个新项目并将我所有的东西都添加到其中,这个想法真的很考验我的生活意愿。 ;) 如果我能打扰的话,我明天可以试试这个。再次感谢。
【讨论】:
【参考方案7】:现在的 VS 项目真的没有什么很神秘的东西 - 都是文本文件等。某些东西必须引用那个类/dll,并且某些东西必须是你项目的一部分。
您是否真的 grep'd 或 findstr'd 整个解决方案树,每个文件,以获取对该异常的引用?
【讨论】:
【参考方案8】:这听起来很奇怪。这是我接下来要检查的内容:
-
检查您的 Properties/AssemblyInfo.cs 文件中是否有任何残留。
检查您的 SuperUI.csproj 文件中是否有任何残留。
删除所有引用并重新添加。
【讨论】:
【参考方案9】:尝试创建一个新项目,并将所有类添加到其中。
【讨论】:
【参考方案10】:grep 你的项目文件夹。它可能是您项目中的隐藏引用,也可能是您的项目引用的项目。如果需要,用记事本清理。
【讨论】:
【参考方案11】:如果您引用任何继承自 SuperException 的类型(即使该类型是在另一个程序集中定义的),则需要对定义 SuperException 的程序集的引用。
其次。
您可能没有引用SuperException
,但您可能引用了SpecializedSuperException
,它派生自SuperException
,或者以其他方式使用SuperException
- 您对SuperException
的项目的grep 不会捕捉到它.
试试NDepend的试用版
【讨论】:
【参考方案12】:这就是像Resharper 这样的工具真正发挥作用的地方——一个简单的 Find Usages 通常会多次告诉我这种“幽灵依赖”。
也许您可以转到 SuperException 类的定义并尝试 Find All References()。您可能还想调查程序集 SuperException 是否对您的主程序集有循环依赖(例如,主程序集依赖于异常程序集依赖于主程序集...)。
【讨论】:
【参考方案13】:当我的 C# 库具有依赖的 C++/CLI 程序集时,我遇到了一个非常相似的程序集引用问题。 问题是我从我的 C# 程序集库中的 C++/CLI 程序集继承了一个公共类。这意味着继承链跨越多个程序集。
我希望任何客户端都足够聪明,可以在 C# 库需要它的任何时候间接加载 C++/CLI 程序集,但即使在编译时也不是这样。
我通过打破跨越这两个程序集库的类之间的继承并改用聚合来解决这个问题。 我的客户终于高兴了,不再需要 C++/CLI 程序集作为依赖项。
用您的话来说,您可能必须确保 SuitableStandardException
不继承自 SuperException
以消除 SuperException.DLL
作为参考。
使用封装而不是继承,并在您的新 SuitableStandardException
中创建一个 SuperException
数据成员。
如果这不能解决问题,您可能有更多类跨越某些程序集的继承,在您的情况下为 SuperAssembly.DLL
和 superException.dll
。
如果你找不到所有这些,试试这个技巧:
将SuperAssembly.DLL
中的所有公共成员和类设为内部。
在 SuperAssembly.DLL 中与SuperException.DLL
交朋友:
[assembly:InternalsVisibleTo("SuperException, PublicKey=0024000004800000....)]
确保他们从已经引用 SuperException.DLL
的任何客户端构建和删除 SuperAssembly.DLL
引用。
【讨论】:
【参考方案14】:grep -R SuperException *
在项目的基础中(首先从某个地方获取grep
)只是为了确定。
【讨论】:
以上是关于C# .NET 中挥之不去的程序集依赖项的主要内容,如果未能解决你的问题,请参考以下文章
例外:无法加载文件或程序集 XXXX 或其依赖项之一。该系统找不到指定的文件
asp.net提示“未能加载文件或程序集“XXXXXXXX.dll”或它的某一个依赖项。找不到指定的模块。”