NuGet包的依赖DLL未复制到输出文件夹

21

我遇到了一个自定义的Nuget包的问题,称之为MyCompany.Library.nupkg。它托管在公司Artifactory Nuget仓库中。这个包依赖于Newtonsoft.Json。但出现一个问题,如果我引用使用该Nuget包的项目时,依赖的DLL文件不会被复制到项目的输出文件夹中。奇怪的是,当我使用另一个包(例如Moq)时,依赖的DLL文件会被复制。

我创建了测试解决方案以重现此问题:

Solution ReferenceTest:

  • Project: SomeLib.dll;引用:
    • MyCompany.Library Nupkg(依赖于Newtonsoft.Json,因此也添加了它)
    • Moq Nupkg(依赖于Castle.Core,也添加了它)
  • Project: MyWinFormsApp.exe;项目引用:
    • SomeLib.csproj

当我查看SomeLib的输出文件夹时,我看到:

  • SomeLib.dll
  • Moq.dll
  • Castle.Core.dll
  • MyCompany.Library.dll
  • Newtonsoft.Json.dll

看起来很好。

但是当我查看MyWinFormsApp的输出文件夹时,缺少Newtonsoft.Json.dll,运行应用程序时会抛出找不到Newtonsoft.Json dll的异常。然而,Castle.Core.dll在MyWinFormsApp的输出文件夹中。

我比较了Moq和MyCompany.Library的nuspecs,没有找到任何重要的区别。

我可以更改所有使用SomeLib的项目以引用Newtonsoft.Json,但那是很多项目,我不想打扰其他开发人员。他们不应该知道SomeLib使用那个程序集。

SomeLib.csproj中的引用如下:

  <ItemGroup>
    <Reference Include="MyCompany.Library, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\packages\MyCompany.Library.1.0.0\lib\net461\MyCompany.Library.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Castle.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
      <HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Moq, Version=4.5.28.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
      <HintPath>..\packages\Moq.4.5.28\lib\net45\Moq.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
      <HintPath>..\packages\Newtonsoft.Json.8.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xml" />
  </ItemGroup>

我的 Nuspec 文件看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <metadata>
    <id>MyCompany.Library</id>
    <version>0.0.0</version>
    <description>MyCompany Core library</description>
    <authors>MyCompany</authors>
    <references>
      <reference file="MyCompany.Library.dll" />
    </references>
    <dependencies>
      <dependency id="Newtonsoft.Json" version="[8.0,9.0.1]" />
    </dependencies>    
  </metadata>
  <files>
    <file src="MyCompany.Library\bin\Release\MyCompany.Library.dll" target="lib\net461"/>
    <file src="MyCompany.Library\bin\Release\MyCompany.Library.pdb" target="lib\net461"/>
    <file src="MyCompany.Library\bin\Release\MyCompany.Library.xml" target="lib\net461"/>
  </files>
</package>

我正在使用Visual Studio 2015专业版。

我的问题:

  1. 为什么Visual Studio没有复制我的相关dll?
  2. 为什么它会复制Moq的依赖项?有什么区别?

感谢任何帮助。

Quido

编辑

我一直在比较Moq和我的包的NUSPEC文件,(完全绝望时)我发现了一个差异。 Moq Nuspec包含:

<dependencies>
  <group targetFramework=".NETFramework4.5">
    <dependency id="Castle.Core" version="3.3.3" />
  </group>
</dependencies>

我的自定义包含:

<dependencies> 
  <dependency id="Newtonsoft.Json" version="[8.0,9.0.1]" /> 
</dependencies>     

我改变了我的依赖项来指定目标框架,现在VisualStudio会复制我的依赖项!

这个NuSpec是我改变的唯一内容,这真正解决了问题。我一直在尝试使用和不使用该targetFramework,结果是一致的(没有targetFramework会失败,有targetFramework会成功)。

所以:问题已经解决,但我不知道为什么......


我在这个主题上找到了另一个问题。https://dev59.com/PXNA5IYBdhLWcg3wAIxP 看起来是VS / MSBuild中的一个错误。那个主题上被接受的答案解释得很清楚。 - Quido
2个回答

2

1.为什么Visual Studio不会复制我的依赖dll文件?

正如您所评论的,如果在解决方案中使用项目依赖项,MSBuild将不会复制引用(DLL文件),以避免在SomeLib项目中污染引用。因此,被引用项目的引用不会复制到输出文件夹。

2.为什么它会复制Moq的依赖项?有什么区别?

正如第一个问题的答案,Moq的依赖项不应该复制到MyWinFormsApp的输出文件夹中。因此,您需要检查是否已将Moq包安装到MyWinFormsApp项目中,并且您可以检查MyWinFormsApp的引用,确保只有SomeLib项目的项目引用。

希望这能帮助您。


6
感谢您的回复。在我看来,您所谓的“参考污染”是“满足依赖关系”的意思。这个解决方案只需要那个程序集。如果没有它,它就无法启动。我非常确定我没有在MyWinFormsApp中添加对Moq的引用。请参考原始帖子中的编辑以获取更多见解... - Quido
不确定你是怎么创建测试解决方案的。你曾经把 SomeLib 项目打包,然后安装到 MyWinFormsApp 项目中吗?还是只是项目引用?我重现的步骤是:创建 SomeLib 项目->添加 Moq nuget 包->创建控制台应用程序项目 MyWinFormsApp->将 SomeLib 项目作为项目引用添加到 MyWinFormsApp 项目中(而不是打包 SomeLib 项目)->构建 MyWinFormsApp 项目。你有什么不同的做法吗? - Leo Liu

-1
在项目中右键点击 "Newtonsoft.json" 引用,选择属性。 在属性页面中检查 "Copy Local" 属性是否设置为 "True"。

3
在SomeLib.csproj文件中,Copy Local属性被设置为true。这就是为什么该DLL会被复制到该项目的输出文件夹中。MyWinFormsApp项目没有对该DLL的引用,因此我无法设置Copy Local属性。 - Quido

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