web-dev-qa-db-de.com

Abhängige DLLs eines NuGet-Pakets werden nicht in den Ausgabeordner kopiert

Ich habe ein Problem mit einem benutzerdefinierten Nuget-Paket, das ich erstellt habe. Nennen wir es MyCompany.Library.nupkg. Es wird auf einem Artifactory Nuget Repo eines Unternehmens gehostet. Dieses Paket hängt von Newtonsoft.Json ab. Aus irgendeinem Grund wird die abhängige DLL nicht in den Ausgabeordner meines Projekts kopiert, wenn ich auf ein Projekt verweise, das dieses Nuget-Paket verwendet. Das Seltsame ist, dass die abhängigen DLLs kopiert werden, wenn ich ein anderes Paket (z. B. Moq anstelle meines eigenen) verwende.

Ich habe eine Testlösung erstellt, um das Problem zu reproduzieren:

Lösungsreferenztest:

  • Projekt: SomeLib.dll; Verweise:
    • MyCompany.Library Nupkg (hängt von Newtonsoft.Json ab, das ist auch hinzugefügt)
    • Moq Nupkg (abhängig von Castle.Core, auch hinzugefügt)
  • Projekt: MyWinFormsApp.exe; Projektreferenz:
    • SomeLib.csproj

Wenn ich mir den Ausgabeordner von SomeLib ansehe, sehe ich:

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

Das sieht gut aus.

Wenn ich jedoch den Ausgabeordner von MyWinFormsApp anschaue, fehlt Newtonsoft.Json.dll, und wenn die Anwendung ausgeführt wird, werden Ausnahmen ausgelöst, dass die Newtonsoft.Json-DLL nicht gefunden wird. Die Castle.Core.dll IS im Ausgabeordner von MyWinFormsApp.

Ich habe die Nuspecs von Moq und MyCompany.Library verglichen und finde keinen signifikanten Unterschied.

Ich könnte das gesamte Projekt ändern, das meine SomeLib verwendet, um auf Newtonsoft.Json zu verweisen, aber das sind viele Projekte, und ich möchte die anderen Entwickler nicht damit belästigen. Sie sollten nicht wissen müssen, dass SomeLib diese Assembly verwendet.

Die Verweise in SomeLib.csproj lauten wie folgt:

  <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>

Mein Nuspec sieht so aus:

<?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>

Ich verwende Visual Studio 2015 Professional.

Meine Fragen:

  1. Warum kopiert Visual Studio meine abhängige DLL nicht?
  2. Warum kopiert es die Abhängigkeiten von Moq? Was ist der Unterschied?

Danke für jede Hilfe.

Quido

EDIT

Ich habe die NUSPEC von Moq und mein eigenes Paket verglichen und (völlig verzweifelt) fand ich einen Unterschied. Das Moq Nuspec enthält:

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

und mein eigenes Paket enthält:

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

Ich habe meine Abhängigkeit geändert, um ein targetFramework anzugeben, und jetzt kopiert VisualStudio meine Abhängigkeit!

Dass NuSpec das einzige ist, was ich geändert habe, und das löst es wirklich. Ich bin mit und ohne targetFramework in eine Situation gegangen und die Ergebnisse sind konsistent (Misserfolg ohne targetFramework und Erfolg mit dem targetFramework).

Also: Problem gelöst, aber ich habe keine Ahnung warum ...

13
Quido

1.Warum kopiert Visual Studio meine abhängige DLL nicht?

Genau wie Sie kommentieren, kopiert MSBuild keine Referenzen (DLL-Dateien), wenn Sie Projektabhängigkeiten in der Lösung verwenden, um eine Referenzverschmutzung im Projekt SomeLib-Projekt zu vermeiden. Die Referenzen des referenzierten Projekts werden also nicht in den Ausgabeordner kopiert.

2. Warum kopiert es die Abhängigkeiten von Moq? Was ist der Unterschied?

Als Antwort auf die erste Frage sollten die Abhängigkeiten von Moq nicht in den Ausgabeordner von MyWinFormsApp kopiert werden. Sie müssen also prüfen, ob Sie das Moq-Paket im MyWinFormsApp-Projekt installiert haben, und Sie können die Referenzen von MyWinFormsApp überprüfen und sicherstellen, dass Sie nur eine Projektreferenz des SomeLib-Projekts haben.

Hoffe das kann dir helfen.

1
Leo Liu-MSFT

Klicken Sie im Projekt mit der rechten Maustaste auf "Newtonsoft.json" und wählen Sie Eigenschaften aus. Wählen Sie auf der Eigenschaftenseite aus, ob die Eigenschaft "Copy Local" auf "True" gesetzt ist.

0
Pankaj Kapare