无法从程序集中加载类型错误

157

我写了以下简单的测试来学习Castle Windsor的Fluent接口:

using NUnit.Framework;
using Castle.Windsor;
using System.Collections;
using Castle.MicroKernel.Registration;

namespace WindsorSample {
    public class MyComponent : IMyComponent {
        public MyComponent(int start_at) {
            this.Value = start_at;
        }
        public int Value { get; private set; }
    } 
    public interface IMyComponent {
        int Value { get; }
    }

    [TestFixture]
    public class ConcreteImplFixture {
        [Test]
        public void ResolvingConcreteImplShouldInitialiseValue() {
            IWindsorContainer container = new WindsorContainer();
            container.Register(Component.For<IMyComponent>().ImplementedBy<MyComponent>().Parameters(Parameter.ForKey("start_at").Eq("1")));
            IMyComponent resolvedComp = container.Resolve<IMyComponent>();
            Assert.AreEqual(resolvedComp.Value, 1); 
        }
    }
}

当我通过TestDriven.NET执行测试时,我会得到以下错误:

System.TypeLoadException : Could not load type 'Castle.MicroKernel.Registration.IRegistration' from assembly 'Castle.MicroKernel, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc'.
at WindsorSample.ConcreteImplFixture.ResolvingConcreteImplShouldInitialiseValue()

当我通过 NUnit GUI 执行测试时,我会得到:

WindsorSample.ConcreteImplFixture.ResolvingConcreteImplShouldInitialiseValue:
System.IO.FileNotFoundException : Could not load file or assembly 'Castle.Windsor, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc' or one of its dependencies. The system cannot find the file specified.

如果我在Reflector中打开我正在引用的程序集,我可以看到它的信息是:

Castle.MicroKernel, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc

出现这种情况可能是因为代码中一些关键的组件没有被正确地引用进来,而且其中肯定包含 Castle.MicroKernel.Registration.IRegistration

具体原因还需进一步排查。

需要说明的是,这些二进制文件是从 Castle 的最新版本 中提取的,虽然我从未使用过 nant 重新编译源代码,但我只是在 bin 目录中拿了这些文件。另外,我应该指出,我的项目编译没有问题。

30个回答

153
如果一个项目引用了另一个项目(例如“Windows应用程序”类型引用了“类库”),并且两者具有相同的程序集名称,那么就会出现此错误。你可以给被引用的项目添加强名称或者(更好的方法)重命名引用项目的程序集(在VS项目属性的“应用程序”选项卡下)。

3
另外,尝试清理输出文件夹。可能会造成相同问题的库重命名,因为旧库和新库都将放置在同一个输出文件夹中。 - Manushin Igor
1
如果你复制粘贴一个项目并且没有正确编辑所有字段,就会导致这个问题! - Michael Parker
1
这对我来说就是这样了,我已经在引用的类库中引用了程序集。我必须进入我的 Web 项目的 web.config 文件,并在卸载 nuGet 包后删除 <dependantAssembly> 引用,以使其正常工作。 - Ivan

129

装配在全局程序集缓存 (GAC) 中或任何可能覆盖你认为正在加载的程序集的地方了吗?这通常是加载错误程序集的结果,对于我来说,这意味着我的 GAC 中通常有某些内容覆盖了我在 bin/Debug 中拥有的版本。


1
我通过浏览dll文件添加程序集,因此GAC不应该参与计算。此外,在解决方案资源管理器中右键单击程序集->在反编译器中打开,可以将其在反编译器中打开,并显示我所期望的所有信息。 - George Mauer
7
如果在全局程序集缓存中已经存在相同名称/版本的程序集,那么无论你如何添加它,都会加载它。 - Eric Schoonover
1
VS.NET会列出您选择的程序集的路径,反射器将打开正确的程序集,但当应用程序执行时,.NET运行时将加载GAC'd程序集。 - Eric Schoonover
11
这已经是这个答案第二次拯救了我,如果我能再投一次票的话,我会再次为它投赞成票。 - whybird
20
(GAK。大声说出来。这个名字的声音就警告你它是什么样子。) - whybird
显示剩余2条评论

18

我最终发现在web.config中有一个旧的类(HttpHandler)的引用,它已不再使用(也不再是有效的引用)。在使用 Visual Studio 运行时它似乎被忽略了(或者该类仍可在我的开发设置中访问?),因此只有在尝试部署到 IIS 时才会出现此错误。

我在web.config中搜索了程序集名称,删除了未使用的处理程序的引用后,这个错误就消失了,一切都运作良好。


1
之前遇到过类似的问题,只是 web.config 中对 DLL 的引用仍然指向 bin 目录中的一个旧版本。而该二进制文件则又引用了一个旧版本的共享 DLL,导致了异常的出现。 - santos

18

我遇到了相同的问题,但与命名空间或项目命名无关。

正如几位用户所提示的那样,这与仍在引用的旧程序集有关。

我建议删除所有项目的“bin”/二进制文件夹,并重新构建整个解决方案。 这将清除任何可能过时的程序集,之后MEF导出我的所有插件都没有问题。


9

在对类名进行重构后,我遇到了以下问题:
Could not load type 'Namspace.OldClassName' from assembly 'Assembly name...'.

停止IIS并删除 Temporary ASP.NET Files 中的内容可以解决此问题。

根据您的项目(32/64位、.net版本等),正确的 Temporary ASP.NET Files 位置可能会有所不同:

  • 64位
    %systemroot%\Microsoft.NET\Framework64\{.netversion}\Temporary ASP.NET Files\
  • 32位
    %systemroot%\Microsoft.NET\Framework\{.netversion}\Temporary ASP.NET Files\
  • 在我的开发机上是这样的(因为可能是IIS Express?)
    %temp%\Temporary ASP.NET Files

9
我遇到了这个错误,无论是在StackOverflow还是其他地方找到的解决方法都没有解决它,但是bmoeskau的回答指引我朝着正确的方向解决问题,这个方法并没有被提及。我的回答与原问题没有直接关联,但我假设有人也会通过谷歌或类似的搜索方式来到这里(就像我一个月后再次遇到这个问题时),所以我在这里发布我的答案。

我的程序集在GAC中,理论上只有一个版本可用。然而,IIS会缓存旧版本并给我报错。我刚刚更改、重建和重新安装了程序集。一种可能的解决方法是使用任务管理器杀掉w3wp.exe。这将强制IIS从GAC中重新读取程序集:问题得到解决。


5
如果这个错误是由于更改命名空间引起的,请确保该项目的文件夹重命名为相同的名称,并关闭VS.NET。使用记事本编辑出现问题的项目,并替换它们的节点:

"RootNamespace>您的项目命名空间的新文件夹名称"RootNamespace> "AssemblyName>您的项目命名空间的新文件夹名称"AssemblyName>


文件夹并不重要,但是在移动和重命名项目后我忘记更改项目默认命名空间。感谢您指引我正确的方向。 - cdonner

4
当我遇到这样的问题时,我发现FUSLOGVW工具非常有用。它会检查程序集绑定信息并为您记录日志。有时库文件丢失,有时GAC中有不同版本正在加载。有时所引用的库的平台会导致问题。该工具清楚地显示了依赖项的绑定是如何解决的,这可能真正帮助您调查/排除问题。
融合日志查看器 / fuslogvw / 程序集绑定日志查看器。在此处查看更多/下载: http://msdn.microsoft.com/en-us/library/e74a18c4.aspx

有没有办法让FUSLOGVW与Visual Studio Designer一起工作?当我尝试编辑我的对话框时(“找不到方法”),Visual Studio Designer会抛出异常,但我知道该方法存在(应用程序运行良好)。据我所见,在Visual Studio Designer中编辑时,FUSLOGVW中似乎没有任何内容显示。 - Jimmy

3

在另一个情况下,我遇到了这个问题:

我正在使用由ILRepack创建的合并程序集。您查询类型的程序集必须是首先传递给ILRepack的程序集,否则它的类型将无法使用。


什么?你能再解释一下吗? - Seabizkit

3
删除我的.dll文件中的.pdb文件解决了我的问题。我猜测这与使用ILMerge创建dll有关。

这就是我所遇到的问题!我不知道ILMerge是什么,但Epicor不喜欢在我的程序集旁边有pdb文件。 - MDave
没有使用ILMerge,但删除所有的PDB文件解决了这个问题。 - hogarth45

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