c# - 为什么在设置对 "System.IO.FileNotFoundException: Could not load file or assembly"的引用时得到 "copylocal=false"?

标签 c# visual-studio unit-testing filenotfoundexception copy-local

情况如下:我正在尝试使用一个名为“TestProject”的测试项目来运行单元测试。它正在测试另一个项目中的一个类,我将其称为“Class1”和“Project1”。

Project1 在运行时对各种 dll 进行一些动态延迟加载,我将其称为“TheDynamicDLLs”。 Project1 通过查找相对于其自己的构建输出路径的目录来查找这些 dll。

问题的第一部分出现在 TestProject 引用 Project1 时。显然,它将新构建的Project1.dll复制到它自己的构建目录中,然后当Project1.dll在相对于其位置的路径中查找TheDynamicDLL时,它找不到它们,因为它是从TestProject的位置运行的,而不是它的位置拥有。

为了解决这个问题,我转到 TestProject 的引用,右键单击 Project1 引用,然后打开其属性。然后我将“复制本地”设置为“False”。我还确保引用的“Path”属性与 Project1 的构建路径相同。

现在我遇到了一个新问题,我什至不知道它是什么。每当我运行单元测试时,它都会失败并报告“System.IO.FileNotFoundException:无法加载文件或程序集[将 Project1 命名为无法找到的程序集的信息]”。

此外,当我尝试调试单元测试时,而不是仅仅运行它,它永远不会抛出异常、提示或任何其他内容,从而阻止我找到有关问题的任何进一步信息。我在测试报告中也找不到任何进一步的有用信息。

以下是完整的测试报告,出于保密目的,其中的名称等已被替换:

Test Name:  Class1_Tests
Test FullName:  TestProject.TestClass.Class1_Tests
Test Source:    c:\Code\Solution1\Tests\TestProject\TestClass.cs : line 175
Test Outcome:   Failed
Test Duration:  0:00:00.0348455

Result Message: 
Test method TestProject.TestClass.Class1_Tests threw exception: 
System.IO.FileNotFoundException: Could not load file or assembly 'Project1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.=== Pre-bind state information ===
LOG: DisplayName = Project1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///C:/Code/Solution1/Tests/TestProject/bin/Debug
LOG: Initial PrivatePath = NULL
Calling assembly : TestProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Code\Solution1\Tests\TestProject\bin\Debug\TestProject.dll.config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Code/Solution1/Tests/TestProject/bin/Debug/Project1.DLL.
LOG: Attempting download of new URL file:///C:/Code/Solution1/Tests/TestProject/bin/Debug/Project1/Project1.DLL.
LOG: Attempting download of new URL file:///C:/Code/Solution1/Tests/TestProject/bin/Debug/Project1.EXE.
LOG: Attempting download of new URL file:///C:/Code/Solution1/Tests/TestProject/bin/Debug/Project1/Project1.EXE.
Result StackTrace:  at TestProject.TestClass.Class1_Tests()

从日志来看,尽管我明确告诉它不要复制到本地,但 TestProject 似乎仍在尝试从其自己的 #$%^ing 构建路径加载 Project1 的 dll。 (咕噜……)

我做错了什么?

最佳答案

!!!请注意:我发布的最初问题是关于我对更深层次问题的解决方案的问题。这个答案是对更深层次问题的解决方案,而不是问题所询问的问题。

进一步解释:最初的问题是当这些引用设置为“CopyLocal=false”时,如何让运行时环境正确加载引用的依赖项。

之所以问这个问题,是因为我一直在设置 copylocal=false 来保持依赖项 dll 在其原始构建路径中运行,即使它是作为不同单元测试项目的一部分加载和运行的,这样它就能够在运行时查找位于相对于其构建路径的文件夹路径中的项目。

这个答案是对第一个问题的答案,消除了首先设置 copylocal=false 的需要。因此,我不会在这里选择我的答案作为最有帮助的。如果有人对直接问题有答案,他们仍然应该发布它,以帮助那些可能因与我不同的原因而遇到该问题的人。

也就是说,这是我对需要设置 copylocal=false 的原因的解决方案:

  1. 将 TheDynamicDLL 添加到 Project1,但不作为引用。只需右键单击解决方案资源管理器中的 Project1 并选择“添加现有项”,然后浏览到每个 dll 位置并将其添加为作为链接。 (添加为链接很重要,这样每当由其 DynamicDLLProject 重建时它都会刷新)。
  2. 右键单击 Project1 中新添加的项目并选择“属性”。将“构建操作”设置为“无”,并将“复制到输出目录”设置为“如果较新则复制” strong> 或“始终复制”
  3. 对 Project1 将/可能在运行时加载的每个动态 dll 重复步骤 1 和 2。
  4. 当然,在 TestProject 中,我将 Project1 引用设置回“Copy Local = True”。

这样做的效果是,虽然动态 dll 实际上并未被引用或编译到 Project1 中(应该是这样,以防止它们在 Project1 运行时急切加载),但任何引用 Project1 并将其 dll 复制到其项目中的项目输出路径,还将复制作为该项目输出的一部分添加的项目(在本例中为 TheDynamicDLL)。

我希望这对那些因与我类似的原因而遇到此问题的人有所帮助。

关于c# - 为什么在设置对 "System.IO.FileNotFoundException: Could not load file or assembly"的引用时得到 "copylocal=false"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24895363/

相关文章:

c# - 使用 C# 以编程方式冷启动 Windows Mobile 6.5 设备

javascript - TypeError:Expect不是函数

unit-testing - 如何在 Xcode 中组织库项目的单元测试?

c# - 自定义 Intellisense Presenter 问题

c# - 在所有其他项目完成构建之前启动多个启动项目之一

c# - 将所有方法/属性/字段大写的工具

python-3.x - 用模拟修补父类(super class)方法

C#-索引属性?

c# - MVVM ListView 多重绑定(bind) SelectedItems + SelectedItem (ListView) + SelectedItem (ComboBox) 到 TextBox.Text。无法正确更新

c# 如何在 foreach 中访问由 int 和 string 组成的对象列表的元素