290

我在我们的测试机器上有一个非常奇怪的错误。错误是:

System.TypeLoadException: Method 'SetShort' in type 'DummyItem' from assembly 'ActiveViewers (...)' does not have an implementation.

我只是不明白为什么。SetShortDummyItem课堂上,我什至重新编译了一个写入事件日志的版本,以确保它不是部署/版本控制问题。奇怪的是调用代码甚至没有调用SetShort方法。

4

41 回答 41

261

注意- 如果此答案对您没有帮助,请花时间向下滚动查看人们此后添加的其他答案。

简短的回答

如果您将方法添加到一个程序集中的接口,然后添加到另一个程序集中的实现类,但您在不引用接口程序集的新版本的情况下重新构建实现程序集,则可能会发生这种情况。

在这种情况下,DummyItem 实现来自另一个程序集的接口。SetShort 方法最近被添加到接口和 DummyItem 中 - 但是包含 DummyItem 的程序集是参考以前版本的接口程序集重建的。因此,SetShort 方法有效地存在,但没有将其链接到接口中的等效方法的魔法酱。

长答案

如果您想尝试重现此内容,请尝试以下操作:

  1. 创建一个类库项目:InterfaceDef,只添加一个类,然后构建:

    public interface IInterface
    {
        string GetString(string key);
        //short GetShort(string key);
    }
    
  2. 创建第二个类库项目:实现(使用单独的解决方案),将 InterfaceDef.dll 复制到项目目录并添加为文件引用,仅添加一个类,然后构建:

    public class ImplementingClass : IInterface
    {
        #region IInterface Members
        public string GetString(string key)
        {
            return "hello world";
        }
    
        //public short GetShort(string key)
        //{
        //    return 1;
        //}
        #endregion
    }
    
  3. 创建第三个,控制台项目:ClientCode,将两个dll复制到项目目录下,添加文件引用,在Main方法中添加如下代码:

     IInterface test = new ImplementingClass();
     string s = test.GetString("dummykey");
     Console.WriteLine(s);
     Console.ReadKey();
    
  4. 运行代码一次,控制台显示“hello world”

  5. 取消注释两个 dll 项目中的代码并重新构建 - 将两个 dll 复制回 ClientCode 项目,重新构建并尝试再次运行。尝试实例化 ImplementingClass 时发生 TypeLoadException。

于 2009-06-04T05:58:26.710 回答
36

除了提问者自己的回答已经说明之外,可能值得注意的是以下内容。发生这种情况的原因是,一个类可能拥有一个与接口方法具有相同签名的方法,而无需实现该方法。以下代码说明了这一点:

public interface IFoo
{
    void DoFoo();
}

public class Foo : IFoo
{
    public void DoFoo() { Console.WriteLine("This is _not_ the interface method."); }
    void IFoo.DoFoo() { Console.WriteLine("This _is_ the interface method."); }
}

Foo foo = new Foo();
foo.DoFoo();               // This calls the non-interface method
IFoo foo2 = foo;
foo2.DoFoo();              // This calls the interface method
于 2009-07-08T18:20:25.620 回答
23

当我的应用程序没有对定义错误消息中的方法使用的类的另一个程序集的引用时,我得到了这个。运行 PEVerify 给出了更多有用的错误:“系统找不到指定的文件。”

于 2009-09-16T21:31:32.717 回答
23

我遇到了同样的消息,这就是我们发现的:我们在我们的项目中使用了第三方 dll。在新版本发布后,我们将项目更改为指向新的 dll 集并成功编译。

当我试图在运行时实例化它们的接口类之一时引发了异常。我们确保所有其他参考都是最新的,但仍然没有运气。我们需要一段时间来发现(使用对象浏览器)错误消息中方法的返回类型是来自新的、未引用的程序集的全新类型。

我们添加了对程序集的引用,错误消失了。

  • 错误消息非常具有误导性,但或多或​​少指向正确的方向(正确的方法,错误的消息)。
  • 即使我们没有使用有问题的方法,也会发生异常。
  • 这让我想到了一个问题:如果在任何情况下都抛出了这个异常,为什么编译器不接受它?
于 2010-05-05T07:03:02.140 回答
18

我在以下情况下收到此错误。

  • 程序集 A 和 B 都引用了 System.Web.Mvc 版本 3.0.0.0
  • 程序集 A 引用了程序集 B,并具有实现了程序集 B 的接口的类,这些类具有从 System.Web.Mvc 返回类的方法。
  • 程序集 A 升级到 System.Web.Mvc 版本 4.0.0.0
  • 程序集 C 运行以下代码(FertPin.Classes.Contact 包含在程序集 A 中):

var target = Assembly.GetAssembly(typeof(FertPin.Classes.Contact));

对我的修复是将程序集 B 中的 System.Web.Mvc 引用升级到 4.0.0.0。现在看起来很明显!

感谢原版海报!

于 2012-11-01T12:31:13.217 回答
14

如果您有一个不正确的签名程序集版本,您可能会收到此错误。这不是这个原因的正常症状,但这是我得到它的场景

  • 一个asp.net项目包含程序集A和程序集B,B是强命名的

  • 程序集 A 使用 Activator.CreateInstance 加载程序集 C(即没有对单独构建的 C 的引用)

  • C 是参考比当前存在的旧版本的程序集 B 构建的

希望对某人有所帮助-我花了很长时间才弄清楚这一点。

于 2009-11-30T16:17:45.697 回答
10

我也有这个错误,它是由引用任何 CPU 程序集的任何 CPU exe 引起的,而该程序集又引用了 x86 程序集。

该异常抱怨 MyApp.Implementations (Any CPU) 中的类上的一个方法,该方法派生 MyApp.Interfaces (Any CPU),但在 fuslogvw.exe 中,我从 MyApp 中发现了一个隐藏的“尝试加载格式不正确的程序”异常.CommonTypes (x86) 两者都使用。

于 2010-08-18T15:13:16.977 回答
7

我不断回到这个......这里的许多答案都很好地解释了问题是什么,而不是如何解决它。

解决方案是手动删除项目发布目录中的 bin 文件。它将清理所有引用并强制项目使用最新的 DLL。

我不建议使用发布工具删除功能,因为这往往会甩掉 IIS。

于 2015-05-01T14:45:20.970 回答
7

我在使用 Autofac 和大量动态程序集加载的上下文中遇到了这个错误。

在执行 Autofac 解析操作时,运行时将无法加载其中一个程序集。错误消息抱怨说Method 'MyMethod' in type 'MyType' from assembly 'ImplementationAssembly' does not have an implementation. 这些症状在 Windows Server 2012 R2 VM 上运行时出现,但在 Windows 10 或 Windows Server 2016 VM 上没有出现。

ImplementationAssembly引用System.Collections.Immutable1.1.37,并包含接口的实现,该IMyInterface<T1,T2>接口在单独的DefinitionAssembly. DefinitionAssembly参考System.Collections.Immutable1.1.36。

IMyInterface<T1,T2>“未实现”的方法具有类型为 的参数IImmutableDictionary<TKey, TRow>,该参数在System.Collections.Immutable.

在程序目录中找到的实际副本System.Collections.Immutable是 1.1.37 版。在我的 Windows Server 2012 R2 VM 上,GAC 包含System.Collections.Immutable1.1.36 的副本。在 Windows 10 和 Windows Server 2016 上,GAC 包含System.Collections.Immutable1.1.37 的副本。仅当 GAC 包含旧版本的 DLL 时才会发生加载错误。

因此,程序集加载失败的根本原因是对System.Collections.Immutable. 接口定义和实现具有相同的方法签名,但实际上依赖于不同的版本System.Collections.Immutable,这意味着运行时不会考虑实现类与接口定义匹配。

将以下绑定重定向添加到我的应用程序配置文件解决了该问题:

<dependentAssembly>
        <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.1.37.0" newVersion="1.1.37.0" />
</dependentAssembly>
于 2017-03-23T07:31:18.130 回答
6

我对此错误消息还有另一个深奥的解决方案。我将目标框架从 .Net 4.0 升级到 4.6,当我尝试构建时,我的单元测试项目给了我“System.TypeLoadException ...没有实现”错误。它还给出了第二条错误消息,该消息是关于“‘BuildShadowTask’任务意外失败”的所谓未实现的方法。这里的建议似乎都没有帮助,所以我搜索了“BuildShadowTask”,并在 MSDN 上找到了一篇文章,导致我使用文本编辑器从单元测试项目的 csproj 文件中删除这些行。

<ItemGroup>
  <Shadow Include="Test References\MyProject.accessor" />
</ItemGroup>

在那之后,两个错误都消失了,项目也建立了。

于 2015-11-13T23:42:27.223 回答
5

我得到了一个“菱形”形状的项目依赖项:

  • 项目 A 使用项目 B 和项目 D
  • 项目 B 使用项目 D

我重新编译了项目 A 但没有重新编译项目 B,这允许项目 B“注入”旧版本的项目 D dll

于 2010-09-23T09:09:16.940 回答
5

我在重命名项目(和程序集名称)时遇到了这种情况,该项目依赖于 ASP.NET 项目。Web 项目中的类型在依赖程序集中实现了接口。尽管从 Build 菜单执行 Clean Solution,但以前名称的程序集仍保留在bin文件夹中,并且当我的 Web 项目执行时

var types = AppDomain.CurrentDomain.
   GetAssemblies().
   ToList().
   SelectMany( s => s.GetTypes() /* exception thrown in this call */ )
;

抛出了上面的异常,抱怨实现的 web 类型中的接口方法实际上没有实现。手动删除 Web 项目bin文件夹中的程序集解决了该问题。

于 2012-05-27T06:39:06.193 回答
4

当我之前在其中一个程序集的单元测试期间启用代码覆盖率时,我也遇到了这个错误。出于某种原因,Visual Studio “缓冲”了这个特定 DLL 的旧版本,即使我已经更新它以实现新版本的接口。禁用代码覆盖消除了错误。

于 2010-09-26T08:02:57.013 回答
4

如果使用 Assembly.LoadFrom(String) 加载程序集并引用已使用 Assembly.Load(Byte[]) 加载的程序集,也会导致此错误。

例如,您已将主应用程序的引用程序集嵌入为资源,但您的应用程序从特定文件夹加载插件。

您应该使用 Load,而不是使用 LoadFrom。以下代码将完成这项工作:

private static Assembly LoadAssemblyFromFile( String filePath )
{
    using( Stream stream = File.OpenRead( filePath ) )
    {
        if( !ReferenceEquals( stream, null ) )
        {
            Byte[] assemblyData = new Byte[stream.Length];
            stream.Read( assemblyData, 0, assemblyData.Length );
            return Assembly.Load( assemblyData );
        }
    }
    return null;
}
于 2011-11-11T15:45:03.333 回答
4

我收到此错误是因为我在框架版本 4.5 上的程序集“C”中有一个类,在框架版本 4.5.1 上的程序集“A”中实现接口并用作程序集的基类“B”也在框架的 4.5.1 版本上。系统在尝试加载程序集“B”时抛出异常。此外,我在所有三个程序集上都安装了一些针对 .net 4.5.1 的 nuget 包。出于某种原因,即使 nuget 引用未显示在程序集“B”中,它也已成功构建。

事实证明,真正的问题是程序集引用了包含接口的 nuget 包的不同版本,并且接口签名在版本之间发生了变化。

于 2015-08-03T05:05:54.307 回答
3

FWIW,当有一个配置文件重定向到引用程序集的不存在版本时,我得到了这个。融合日志为胜利!

于 2009-12-10T17:54:54.047 回答
3

对涉及托管 C++ 的此类问题的另一种解释。

如果您尝试存根在使用托管 C++ 创建的具有特殊签名的程序集中定义的接口,您将在创建存根时遇到异常。

对于 Rhino Mocks 和任何使用System.Reflection.Emit.

public interface class IFoo {
  void F(long bar);
};

public ref class Foo : public IFoo {
public:
  virtual void F(long bar) { ... }
};

接口定义获得以下签名:

void F(System.Int32 modopt(IsLong) bar)

请注意,C++ 类型long映射到System.Int32(或简单地int在 C# 中)。正如 Ayende Rahien 在 Rhino Mocks 邮件列表中所说,modopt这是导致问题的有点模糊 。

于 2011-05-12T15:07:17.793 回答
3

我刚刚将解决方案从 MVC3 升级到 MVC5,并开始从我的单元测试项目中收到相同的异常。

检查所有寻找旧文件的引用,最终发现我需要在我的单元测试项目中为 Mvc 做一些 bindingRedirects。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>
于 2014-03-25T01:21:41.407 回答
3

就我而言,它有助于重置 WinForms 工具箱。

在设计器中打开 a 时出现异常Form;但是,编译和运行代码是可能的,并且代码的行为符合预期。异常发生在本地UserControl实现我引用的库之一的接口中。更新此库后出现错误。

UserControl已在 WinForms 工具箱中列出。可能 Visual Studio 保留了对库的过时版本的引用,或者在某处缓存了过时的版本。

以下是我从这种情况中恢复过来的方法:

  1. 右键单击 WinForms 工具箱,然后单击Reset Toolbox上下文菜单中的 。(这会从工具箱中删除自定义项目)。
    在我的情况下,工具箱项目恢复到默认状态;但是,工具箱中缺少指针箭头。
  2. 关闭 Visual Studio。
    在我的情况下,Visual Studio 因违规异常而终止并中止。
  3. 重新启动 Visual Studio。
    现在一切都在顺利进行。
于 2014-09-17T19:30:32.957 回答
3

在我的例子中,我之前mylib在 repo 之外的同级文件夹中引用了一个项目 - 我们称之为v1.0.

|-- myrepo
|    |-- consoleApp
|    |-- submodules
|         |-- mylib (submoduled v2.0)
|-- mylib (stale v1.0)

后来我做得很好,并通过一个 git 子模块使用它 - 让我们称之为v2.0. 然而,一个项目consoleApp没有正确更新。它仍在引用v1.0我的 git 项目之外的旧项目。

令人困惑的是,即使*.csproj明显错误并指向v1.0,Visual Studio IDE 仍将路径显示为v2.0项目!F12 检查接口和类也去了v2.0版本。

编译器放入 bin 文件夹的程序集是v1.0版本,因此令人头疼。

IDE 对我撒谎的事实使我更难意识到错误。

解决方案:从中删除项目引用ConsoleApp并重新添加它们。

一般提示:从头开始重新编译所有程序集(如果可能,当然不能用于 nuget 包)并检查bin\debug文件夹中的日期时间戳。任何过时的组件都是您的问题。

于 2016-10-28T11:27:27.083 回答
3

我面临几乎同样的问题。我在挠头是什么导致了这个错误。我交叉检查,所有方法都实现了。

在谷歌搜索中,我得到了这个链接。根据@Paul McLink 的评论,这两个步骤解决了这个问题。

  1. 重新启动 Visual Studio
  2. 清理,构建(重建)

并且错误消失了

重启 VS 插件

谢谢保罗:)

希望这可以帮助遇到此错误的人:)

于 2017-02-10T13:18:29.500 回答
2

由于选择了 x86 构建类型,我在 WCF 服务中得到了这个,导致垃圾箱位于 bin\x86 而不是 bin 下。选择 Any CPU 会导致重新编译的 DLL 转到正确的位置(我不会首先详细说明这是如何发生的)。

于 2009-07-28T14:16:50.073 回答
2

我在运行单元测试时也遇到了这个问题。该应用程序运行良好,没有错误。在我的案例中,问题的原因是我关闭了测试项目的构建。重新启用我的测试项目的构建解决了这些问题。

于 2012-09-10T11:38:04.280 回答
2

我在 Visual Studio Pro 2008 中看到了这一点,当时两个项目构建了同名的程序集,一个是类库 SDF.dll,另一个是引用了程序集名称为 sdf.exe 的库。当我更改引用程序集的名称时,异常消失了

于 2012-11-09T17:22:15.447 回答
2

这仅仅意味着在我的案例中实施项目已经过时了。包含接口的 DLL 已重建,但实现 dll 已过时。

于 2013-09-16T04:02:47.260 回答
2

这是我对这个错误的看法。

添加了一个extern方法,但是我的粘贴有问题。DllImportAttribute得到了注释掉的行。

/// <returns>(removed for brevity lol)</returns>[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindowVisible(IntPtr hWnd);

确保属性实际上包含在源中修复了该问题。

于 2015-04-01T19:30:32.580 回答
1

我有同样的问题。我发现我的程序集(由主程序加载)有一些“复制本地”设置为 true 的引用。这些参考的本地副本正在寻找同一文件夹中的其他参考,由于其他参考的“本地复制”设置为 false,因此这些参考不存在。删除“意外”复制的引用后,错误消失了,因为主程序设置为查找引用的正确位置。显然,引用的本地副本搞砸了调用顺序,因为使用这些本地副本而不是主程序中存在的原始副本。

带回家的消息是,由于缺少加载所需程序集的链接而出现此错误。

于 2016-01-04T07:57:01.990 回答
1

就我而言,我试图用来TypeBuilder创建一个类型。TypeBuilder.CreateType抛出了这个异常。MethodAttributes.Virtual我最终意识到,在调用TypeBuilder.DefineMethod有助于实现接口的方法时,我需要添加属性。这是因为没有这个标志,该方法不会实现接口,而是一个具有相同签名的新方法(即使没有指定MethodAttributes.NewSlot)。

于 2016-12-21T15:03:16.257 回答
1

作为附录:如果您更新用​​于生成伪造程序集的 nuget 包,也会发生这种情况。假设您安装了 nuget 包的 V1.0 并创建了一个假货程序集“fakeLibrary.1.0.0.0.Fakes”。接下来,您更新到最新版本的 nuget 包,比如 v1.1,它向接口添加了一个新方法。Fakes 库仍在寻找该库的 v1.0。只需删除假组件并重新生成它。如果这是问题,这可能会解决它。

于 2017-01-20T21:13:45.273 回答
1

最近一次 Windows 更新后,我收到了这个错误。我有一个服务类设置为从接口继承。该接口包含一个返回 ValueTuple 的签名,这是 C# 中的一个相当新的功能。

我能猜到的是windows update安装了一个新的,但甚至明确引用它,更新绑定重定向等......最终结果只是将方法的签名更改为“标准”我猜你可以说。

于 2017-12-13T13:47:04.830 回答
1

我今天收到此错误。我的问题是 - 不要在 TFS 中获取最新版本。在服务器中是带有接口的 dll,其中一种方法被修改。我和一个旧的一起工作 - 在我的电脑上它的作品。如何修复:获取最新版本、重建

于 2018-11-22T12:04:23.203 回答
1

还有另一种方法来获得这个:

class GenericFoo<T> {}

class ConcreteFoo : GenericFoo<ClassFromAnotherAssembly> {}

程序集中的代码不引用 ClassFromAnotherAssembly 的程序集。

var foo = new ConcreteFoo(); //kaboom

当 ClassFromAnotherAssembly 是 ValueTuple 时,这发生在我身上。

于 2019-01-10T17:16:33.777 回答
1

当接口引用了“特定版本”设置为“真”的第 3 方 dll(MWArray)而实现的类引用了相同的 dll 但“特定版本”设置为“假”时,我遇到了这种情况,所以类和接口对同一个dll有不同的版本引用。

将两者都设置为“特定版本”:“假”或“真”(取决于您需要什么)修复它。

于 2021-06-13T12:17:36.060 回答
1

当我尝试使用自定义 AssemblyLoadContext(不创建 AppDomain)和共享类型(您需要使用它来调用插件方法而无需反射的接口)在 dot net 5 中实现插件程序集加载时,我遇到了这个问题。该线程中的任何内容都没有帮助我。这是我为解决此问题所做的工作:

  1. 为了允许毫无问题地调试插件加载 - 将项目输出路径设置为托管应用程序 bin 文件夹。您将调试插件项目构建后获得的相同程序集。这可能是临时更改(仅用于调试)。
  2. 要修复 TypeLoadException,您需要将所有“合同程序集”引用的程序集加载为共享程序集(运行时程序集除外)。检查加载器上下文实现(在构造函数中加载 sharedAssemblies):

    public class PluginAssemblyLoadContext : AssemblyLoadContext
    {
        private AssemblyDependencyResolver _resolver;
        
        private IDictionary<string, Assembly> _loadedAssemblies;
        
        private IDictionary<string, Assembly> _sharedAssemblies;

        private AssemblyLoadContext DefaultAlc;

        private string _path;

        public PluginAssemblyLoadContext(string path, bool isCollectible, params Type[] sharedTypes)
             : this(path, isCollectible, sharedTypes.Select(t => t.Assembly).ToArray())
        {
        }

        public PluginAssemblyLoadContext(string path, bool isCollectible, params Assembly[] sharedAssemblies)
             : base(isCollectible: isCollectible)
        {

            _path = path;

            DefaultAlc = GetLoadContext(Assembly.GetExecutingAssembly()) ?? Default;

            var fileInfo = new FileInfo(_path);
            if (fileInfo.Exists)
            {
                _resolver = new AssemblyDependencyResolver(_path);

                _sharedAssemblies = new Dictionary<string, Assembly>(StringComparer.OrdinalIgnoreCase);
                foreach (var a in sharedAssemblies.Distinct())
                {
                    LoadReferencedAssemblies(a);
                }

                _loadedAssemblies = new Dictionary<string, Assembly>();

                var assembly = LoadFromAssemblyPath(fileInfo.FullName);

                _loadedAssemblies.Add(fileInfo.FullName, assembly);
            }
            else
            {
                throw new FileNotFoundException($"File does not exist: {_path}");
            }
        }

        public bool LoadReferencedAssemblies(Assembly assembly)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException(nameof(assembly));
            }
            if (string.IsNullOrEmpty(assembly.Location))
            {
                throw new NotSupportedException($"Assembly location is empty string or null: {assembly.FullName}");
            }
            var alc = GetLoadContext(assembly);
            if (alc == this)
            {
                throw new InvalidOperationException($"Circular assembly loader dependency detected");
            }
            if (!_sharedAssemblies.ContainsKey(assembly.Location))
            {
                _sharedAssemblies.Add(assembly.Location, assembly);

                foreach (var an in assembly.GetReferencedAssemblies())
                {
                    var ra = alc.LoadFromAssemblyName(an);
                    LoadReferencedAssemblies(ra);
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        public IEnumerable<Type> GetCommandTypes<T>()
        {
            var cmdType = typeof(T);
            return _loadedAssemblies.Values.SelectMany(a => a.GetTypes()).Where(t => cmdType.IsAssignableFrom(t));
        }

        public IEnumerable<T> CreateCommands<T>(Assembly assembly)
        {
            foreach (var cmdType in GetCommandTypes<T>())
            {
                yield return (T)Activator.CreateInstance(cmdType);
            }
        }

        protected override Assembly Load(AssemblyName assemblyName)
        {
            var path = _resolver.ResolveAssemblyToPath(assemblyName);
            if (path != null)
            {
                if (_sharedAssemblies.ContainsKey(path))
                {
                    return _sharedAssemblies[path];
                }
                if (_loadedAssemblies.ContainsKey(path))
                {
                    return _loadedAssemblies[path];
                }
                return LoadFromAssemblyPath(path);
            }     
            return DefaultAlc.LoadFromAssemblyName(assemblyName);
        }
    }

用法:


var loader = new PluginAssemblyLoadContext(fullPath, false, typeof(IPluginCommand));
loader.CreateCommands<IPluginCommand>()...
于 2021-09-20T09:39:47.870 回答
0

只是为了补充我的经验,因为它没有在其他答案中涵盖:

在 MsTest 中运行单元测试时遇到了这个问题。

被测试的类在一个签名的程序集中。

此程序集的不同版本恰好在 GAC 中(但具有相同的程序集版本号)。

强命名程序集的依赖关系解析算法与未签名程序稍有不同,因为首先检查 GAC。

因此,MsTest 选择了 GAC 的程序集,而不是使用 bin 文件夹中的程序集,并尝试针对它运行测试,这显然不起作用。

解决方案是删除 GAC 的程序集。

请注意,对我来说,线索是在运行测试时构建服务器上没有发生这种情况,因为构建将使用新的程序集版本号编译程序集。这意味着 GAC 中的旧版本程序集将不会被拾取。

此外,如果您由于某种原因无法访问 GAC,我在这里找到了一个潜在的解决方法:https ://johanleino.wordpress.com/2014/02/20/workaround-for-unit-testing-code-that-reside-in -gac/

于 2018-06-27T14:11:36.567 回答
0

我遇到了这个问题,只有我的本地机器有问题。我们小组中的其他开发人员和我的虚拟机都没有这个问题。

最后,它似乎与“目标包”Visual Studio 2017 有关

  • 打开 Visual Studio 安装程序
  • 选择修改
  • 转到第二个顶部选项卡“单个组件”
  • 查看您选择了哪些框架和定位包。
  • 我没有选择两个最新的定位包
  • 我还注意到我没有选择“高级 ASP.NET 功能”,而其他机器有。
  • 选择并安装了新项目,现在一切都很好。
于 2018-09-28T14:36:31.207 回答
0

我们的问题通过更新 Windows 解决了!我们的 Web 应用程序位于 .Net 4.7.1 和 c# 7.0 上。当我们在不同的窗口中进行测试时,我们了解到问题将通过更新窗口来解决。实际上,在 Windows 10(版本 1703)和 Windows Server 2012(去年未更新)中也发现了该问题。两个都更新后,问题就解决了。事实上,asp.net 次要版本(C:\Windows\Microsoft.NET\Framework64\v4.0.30319 中的 clr.dll 版本的第三部分)在更新后发生了一些变化。

于 2019-05-16T06:20:23.820 回答
0

当我的集成测试项目试图加载一个不包含接口依赖解析的 DLL 时,我遇到了这个错误:

  1. 集成测试项目(参考 Main Project 但不参考 StructureMap)
  2. 主项目(参考 StructureMap 项目 - 在类构造函数中使用接口)
  3. StructureMap 项目 (IoC - For().Use();)

这导致错误被抛出,因为它找不到具体的实现。我在测试配置中排除了 DLL,错误消失了

于 2019-12-26T13:46:37.060 回答
0

对我来说,解决方案与实现接口的项目设置了“注册 COM 互操作”属性这一事实有关。取消选中此选项为我解决了这个问题。

于 2020-10-15T16:21:18.737 回答
0

为我解决问题的方法是将以下内容添加到ProjectReference和/或正在加载的程序集中PackageReference<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>

这使我的项目文件看起来像这样:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
  </PropertyGroup>

  <!-- For a package -->
  <ItemGroup>
    <PackageReference Include="SomePackage" Version="x.x.x.x">
      <Private>false</Private>
      <ExcludeAssets>runtime</ExcludeAssets>
    </PackageReference>
  </ItemGroup>

  <!-- For a project -->
  <ItemGroup>
    <ProjectReference Include="..\SomeProject\SomeProject.csproj">
      <Private>false</Private>
      <ExcludeAssets>runtime</ExcludeAssets>
    </ProjectReference>
  </ItemGroup>
</Project>
于 2021-03-07T14:11:28.443 回答
-1

另一种可能性是在依赖项中混合发布和调试版本。例如,程序集 A 依赖于程序集 B,A 是在 Debug 模式下构建的,而 GAC 中 B 的副本是在 Release 模式下构建的,反之亦然。

于 2015-05-20T13:41:03.403 回答