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

时间:2008-09-24 01:09:35

标签: .net

我在尝试学习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

可能发生什么事?

我应该提到二进制文件是从latest build of Castle获取的,虽然我从未使用过nant因此我没有费心从源代码重新编译,只是把文件放在bin目录中。我还应该指出,我的项目编译没有任何问题。

29 个答案:

答案 0 :(得分:117)

如果您有一个项目引用另一个项目(例如“引用”类库“的”Windows应用程序“类型)并且两者具有相同的程序集名称,则会出现此错误。您可以强烈命名引用的项目,或者(甚至更好)重命名引用项目的程序集(在VS中项目属性的“应用程序”选项卡下)。

答案 1 :(得分:93)

是否在全局程序集缓存(GAC)中的程序集或可能覆盖您认为正在加载的程序集的任何位置?这通常是加载错误程序集的结果,对我而言,这意味着我通常在GAC中有一些内容覆盖了bin / Debug中的版本。

答案 2 :(得分:16)

很抱歉疏通一个陈旧的回答问题,但上面没有提到我的解决方案,所以我想我会把我的答案添加到长尾......

我最终对web.config中的一个类(一个HttpHandler)有一个旧的引用,它不再被使用(并且不再是一个有效的引用)。出于某种原因,它在Studio中运行时被忽略了(或者我的开发设置中仍然可以访问该类?)因此我尝试部署到IIS时只出现此错误。我在web.config中搜索了程序集名称,删除了未使用的处理程序引用,然后这个错误消失了,一切都很好。希望这有助于其他人。

答案 3 :(得分:10)

我有同样的问题,对我来说它与命名空间或项目命名无关。

但正如一些用户所暗示的那样,它仍与被引用的旧装配有关。

我建议删除所有项目的所有“bin”/二进制文件夹,并重新构建整个解决方案。这会淘汰任何可能过时的组件,然后MEF导出我的所有插件而没有问题。

答案 4 :(得分:8)

我收到了这个错误,我在StackOverflow或其他地方找不到的任何东西解决了它,但是bmoeskau对这个问题的回答指出了我正确的修复方向,这还没有被提及作为答案。我的答案与原始问题没有严格的关系,但是我在这里发布它是假设有这个问题的人会通过搜索谷歌或类似的东西在这里找到方法(就像我一个月后再次咬我一样) ,arg!)。

我的程序集在GAC中,因此理论上只有一个版本的程序集可用。 除了 IIS有助于缓存旧版本并给我这个错误。我刚刚更改,重建并重新安装了GAC中的程序集。一种可能的解决方案是使用任务管理器来终止 w3wp.exe 。这迫使IIS从GAC重新读取程序集:问题已解决。

答案 5 :(得分:3)

Version = 1.0.3.0表示Castle RC3,但是流畅的界面是在RC3发布几个月后开发的。因此,看起来您有版本控制问题。也许你已经在GAC注册了Castle RC3并且正在使用那个......

答案 6 :(得分:3)

我偶尔会得到这个,并且总是要在GAC中安装程序集

答案 7 :(得分:3)

当我遇到这样的问题时,我发现FUSLOGVW工具非常有帮助。它正在检查程序集绑定信息并为您记录它。有时库缺失,有时GAC有不同的版本正在加载。有时,引用库的平台会导致问题。这个工具清楚地说明了依赖关系&#39;绑定正在解决,这可能真的可以帮助您调查/调试您的问题。

Fusion Log Viewer / fuslogvw / Assembly Binding Log Viewer。查看更多/在此处下载:http://msdn.microsoft.com/en-us/library/e74a18c4.aspx

答案 8 :(得分:3)

为dll删除我的.pdb文件为我解决了这个问题。我猜这与dll是使用ILMerge创建的事实有关。

答案 9 :(得分:3)

如果更改命名空间导致此错误,请将该项目的文件夹重命名为同名, 并关闭VS.NET 编辑具有记事本问题的项目并替换节点

&#34;&RootNamespace GT; New_Name_Of_Folder_Of_Your_Project_Namespace&#34;&RootNamespace GT;     &#34;&的AssemblyName GT; New_Name_Of_Folder_Of_Your_Project_Namespace&#34;&的AssemblyName GT;

答案 10 :(得分:2)

可能不太可能,但对我而言,这是因为我的应用程序尝试加载具有相同程序集名称的库(xxx.exe加载xxx.dll)。

答案 11 :(得分:2)

我有同样的问题。我刚刚通过GAC更新程序集解决了这个问题。

要在开发机器上使用gacutil,请访问: Start -> programs -> Microsoft Visual studio 2010 -> Visual Studio Tools -> Visual Studio Command Prompt (2010)

我使用这些命令分别卸载和重新安装。

gacutil /u myDLL

gacutil /i "C:\Program Files\Custom\mydllname.dll"

注意:在我的情况下,我没有卸载我的dll,我刚刚使用当前路径更新了dll。

答案 12 :(得分:2)

当尝试在针对针对弹出错误的应用程序所共有的引用的不同版本构建的程序集中(通过反射)加载类型时,我遇到了这种情况。

由于我确定程序集的两个版本中的类型均未更改,因此我最终创建了一个自定义程序集解析器,该程序将缺少的程序集映射到我的应用程序已加载的程序集。最简单的方法是将静态构造函数添加到程序类中,如下所示:

using System.Reflection
static Program()
{
    AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => {
        AssemblyName requestedName = new AssemblyName(e.Name);

        if (requestedName.Name == "<AssemblyName>")
        {
            // Load assembly from startup path
            return Assembly.LoadFile($"{Application.StartupPath}\\<AssemblyName>.dll");
        }
        else
        {
            return null;
        }
    };
}

这当然假定程序集位于应用程序的启动路径中,并且可以轻松进行调整。

答案 13 :(得分:2)

我在考虑了一个班级名称之后遇到了这个问题:
Could not load type 'Namspace.OldClassName' from assembly 'Assembly name...'.

停止IIS并删除Temporary ASP.NET Files中的内容为我修复了它。

取决于你的项目(32 / 64bit,.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

答案 14 :(得分:2)

又一个解决方案:旧的DLL指向彼此并由Visual Studio在

中缓存

C:\Users\[yourname]\AppData\Local\Microsoft\VisualStudio\10.0\ProjectAssemblies

退出VS,删除此文件夹中的所有内容,鲍勃是你的叔叔。

答案 15 :(得分:2)

在另一个原因中碰到这个:

我使用的是使用ILRepack创建的合并程序集。您要查询类型的程序集必须是传递给ILRepack的第一个程序集,否则其类型将不可用。

答案 16 :(得分:2)

在另一个原因中碰到这个:

在发布模式下运行单元测试,但正在加载的库是尚未更新的调试模式版本

答案 17 :(得分:1)

我在使用MSTest作为测试框架的Visual Studio 2017中遇到了类似的问题。运行某些(不是全部)单元测试时,我收到了System.TypeLoadException异常,但是调试时这些单元测试会通过。我最终做了以下解决问题的操作:

  1. 在解决方案中打开Local.testsettings文件
  2. 转到“单元测试”设置
  3. 取消选中“对测试目录中的程序集使用加载上下文”。复选框

执行这些步骤后,所有单元测试在运行时就开始通过。

答案 18 :(得分:1)

删除解决方案中的程序集签名后,我遇到了与上述相同的情况。这些项目无法建立。

我发现其中一个项目引用了StrongNamer NuGet软件包,该软件包修改了构建过程并尝试对未签名的Nuget软件包进行签名。

在删除StrongNamer程序包之后,我能够再次构建项目,而无需对程序集进行签名/强命名。

答案 19 :(得分:1)

如果这是Windows应用程序,请尝试检查全局程序集缓存(GAC)中是否存在重复项。某些东西覆盖了您的bin / debug版本。

如果这是一个Web应用程序,则可能需要在服务器上删除并重新上传。如果要发布,则可能需要选中“删除所有现有文件,然后再发布”复选框。根据Visual Studio版本的不同,它应该位于“发布”>“设置”>“文件发布选项”中 Delete all existing files prior to publish

答案 20 :(得分:1)

在桌面可执行项目中更新引用的dll后,我遇到了同样的错误。这个问题就像这里提到的人们提到了一个旧的参考资料并且很容易解决,但这里没有提到,所以我认为这可能会节省其他人的时间。

无论如何我更新了dll A并从另一个引用的dll得到错误让我们把它称为B这里dll A引用了dll B.

更新dll B解决了这个问题。

答案 21 :(得分:1)

将您的DLL添加到GAC(全局程序集缓存)

Visual Studio命令提示符=&gt;以管理员身份运行

gacutil / i&#34; dll文件路径&#34;

您可以看到添加的程序集C:\ Windows \ system32 \

它还将解决dll缺失或&#34;无法加载文件或程序集&#34;在SSIS脚本任务

答案 22 :(得分:1)

当您在GAC中部署了一个版本的程序集但尚未使用可能已在IDE上的程序集上添加的新类进行更新时,通常会发生这种情况。因此,请确保使用您在项目中可能进行的更改来更新GAC上的程序集。

E.g。如果您有一个Common库类,并且在该类库中您有Common.ClassA类型并将其部署到强名称的GAC。稍后您将添加另一个名为Common.ClassB的类型,并在IDE上运行代码,而无需先使用新添加的Common.ClassB类型部署对Common的GAC所做的更改。

答案 23 :(得分:1)

您可以使用* .config中的绑定重定向来解决此问题。 http://blogs.msdn.com/b/dougste/archive/2006/09/05/741329.aspx在较新的框架中使用旧的.net组件进行了很好的讨论。 http://msdn.microsoft.com/en-us/library/eftw1fys(vs.71).aspx

答案 24 :(得分:0)

我想提一些额外的事情并做一个结论。

通常,正如其他人所解释的,当在运行时加载预期类型(在现有程序集中)出现问题时,会引发此异常。更具体地说,每当加载过时的程序集(并且不包含所需类型)时。或者当已经加载了不包含预期类型的​​具有不同版本或构建的程序集时。

另外,我必须提到它似乎很少,但它可能是运行时限制或编译器错误(假设编译器没有否定某些东西,只是编译了有问题的代码),但运行时抛出 System.TypeLoadException 异常。是的;这真的发生在我身上!

一个例子(女巫发生在我身上)

考虑一个 struct,它在自身内部定义了一个其自身类型的可为空的字段。定义这样的归档不可为空,会给你带来编译时错误并阻止你构建(显然这种行为有一个合乎逻辑的原因)。但是可空结构体呢?实际上,可为空的值类型在后面是 Nullable<T>。由于 c# 编译器没有阻止我以这种方式定义,我尝试了它并构建了项目。但是我得到运行时异常 System.TypeLoadException: 'Could not load type 'SomeInfo' from assembly ... ',并且在我的环境中加载我的代码部分似乎有问题(否则,我们可能会说:编译器至少没有真正执行编译过程):

public struct SomeInfo
{
   public SomeInfo? Parent { get; } 
   
   public string info { get; }
}

我的环境规格:

  • Visual Studio 2019 16.4.4
  • 语言版本:c# 7.3
  • 项目类型:netstandard 2.0.3 库
  • 运行时:经典 DotNetFramework 4.6.1

(我检查并确保编译的程序集是最新的并且实际上是新编译的。甚至,我扔掉了所有bin目录并刷新了整个项目。即使我在新的解决方案中创建了一个新项目并进行了测试,但是这样的结构会产生异常。)

这似乎是运行时限制(逻辑上或技术上)或错误或其他相同问题,因为 Visual Studio 不会阻止我编译,而且我的代码的其他较新部分(不包括此结构)执行正常。 将 struct 更改为 class,编译后的程序集也包含并执行该类型。

我不知道详细解释为什么在我的环境中会发生这种行为,但我遇到了这种情况。

结论

检查情况:

  • 当覆盖引用的程序集的相同(可能较旧)程序集已存在于 GAC 中时。

  • 当需要重新编译但未自动执行(因此引用的程序集未更新)并且需要手动执行构建或修复解决方案构建配置时。

  • 当自定义工具或中间件或第三方可执行文件(例如测试运行工具或 IIS)从缓存中加载该程序集的旧版本并且需要清理某些内容或导致重置某些内容时。

  • 当未分配的配置导致自定义工具或中间件或加载程序集的第三方可执行文件要求不再存在的类型时,并且需要更新配置或清理某些内容(例如删除 http正如@Brian-Moeskau 所说,IIS 部署的 web.config 文件中的处理程序)

  • 当运行时执行编译后的程序集时存在逻辑或技术问题(例如,当编译器编译了一个有问题的代码时,正在使用的运行时无法理解或执行它),正如我所面临的。< /p>

答案 25 :(得分:0)

通常找不到dll,或者dll存在,但是找不到新的类。

  1. 如果dll不存在,直接更新dll

  2. 如果有dll,拿下来用ILSPY看看里面有没有报错的类。

如果没有,重建dll并重新上传。

答案 26 :(得分:0)

我尝试了以上大部分方法,但没有一个对我有用。

这是我的问题。

我将一个 c# 项目从我的本地机器 (Windows 10) 移动到服务器 (Windows Server 2008 R2)。尝试从我的 UnitTest 项目运行测试时,我开始收到“无法加载程序集”错误。

这是我的解决方案。

我从解决方案中删除了测试项目,该解决方案是一个单元测试项目 .NET Framework。我还确保删除了该项目。然后我创建了一个新的 MSTest 测试项目 .NET Core 项目。

答案 27 :(得分:0)

我在尝试加载 Blazor 解决方案中的 .NET 5 C# MVC 组件时遇到此错误,该解决方案将 Blazor 组件分解为解决方案中的自己的项目:

enter image description here

我的 DTO 对象专门用于 Blazor 内容,并且没有对 AspNetCore.Mvc 内容的引用(因为这会破坏 Blazor)。

奇怪的是,当我尝试仅使用我需要的对象加载组件时,就像这样(在 MVC View 中):

<component type="typeof(My.Client.Components.MyComponent)" render-mode="WebAssemblyPrerendered"
       param-OpenYearMonth="Model.OpenYearMonth?.ToDTO()" />

我在浏览器控制台中遇到与 OP 相同的错误。但是,出于某种奇怪的原因,只需添加一个额外的虚拟参数即可使其加载正常:

<component type="typeof(My.Client.Components.MyComponent)" render-mode="WebAssemblyPrerendered"
       param-Whatever="new List<My.DTO.Models.Whatever>()"
       param-OpenYearMonth="Model.OpenYearMonth?.ToDTO()" />

认为问题是组件在没有加载 DTO 程序集的情况下被渲染?可能是?它没有多大意义,当然看起来像是 MVCBlazor 中的错误......但我想至少有一些解决方法。我还尝试了一些 Task.Delay 实验,认为 DTO 程序集可能仍在加载或其他什么,但这并没有帮助。我还尝试使用此 ViewModel.OpenYearMonth?.ToDTO() 中创建一个局部变量并将该局部变量传递给组件......再次没有帮助。当然,我也尝试了这篇文章的答案中的所有解决方案,但都没有帮助。不要问这个问题浪费了多少小时...

答案 28 :(得分:-2)

我刚刚使用命令提示符运行iisreset命令解决了这个问题... 当我遇到这样的错误时,我总是做的第一件事。