Including referenced project DLLs in nuget package [.Net Core RC3 *.csproj file]

17,208

Solution 1

There is now a more up-to-date workaround described here. Simply add the TargetsForTfmSpecificBuildOutput and Target nodes to your .csproj file as shown below.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
  </PropertyGroup>
  <Target Name="CopyProjectReferencesToPackage" DependsOnTargets="ResolveReferences">
    <ItemGroup>
      <BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
    </ItemGroup>
  </Target>
</Project>

Official documentation for this extension point in the pack target can be found here.

You might also then want to add the attribute PrivateAssets="All" to the ProjectReference element to suppress that project from appearing as a NuGet dependency in the generated package, e.g.:

<ProjectReference Include="MyNonNugetDependentProject.csproj" PrivateAssets="All" />

Solution 2

This appears to be a known limitation with the built-in NuGet packaging for core projects in Visual Studio 2017 and is discussed here:

https://github.com/NuGet/Home/issues/3891

In that discussion thread there is a hack that worked for me:

https://github.com/NuGet/Home/issues/3891#issuecomment-309792369

<ItemGroup>
  <_PackageFiles Include="$(OutputPath)\ReferencedProjectDll.dll">
    <BuildAction>None</BuildAction>
    <PackagePath>lib\net45\</PackagePath>
  </_PackageFiles>
</ItemGroup>

Note that you need to change the assembly name AND you might need to also change the package path to match the version of .NET Framework you are using. Above example is for 4.5 but you might be on the more current 4.6.

Solution 3

We could not include referenced project DLLs with three or above projects.

For example, the ReferenceLibrary.dll will be added to References for Library1 when project Library1 reference to project ReferenceLibrary. But only the Library1.dll will be add to the References of test app project when you reference project Library1 to project test app. The referenced project DLLs “Referencelibrary” will be omitted . See Flexible Project-to-Project References for more detail.

If you want to embed the DLLs for ReferenceLibrary inside Library1's nuget package and reference it to the test app project, you can add the ReferenceLibrary project reference to test app project after add the reference project Library1 or set ReferenceLibrary.dll as a dependence of Library1 project, you can add the below entries into Library1.csproj, then package the Library1 and install this package to test app via NuGet:

  <ItemGroup>
    <Reference Include="ReferenceLibrary, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\packages\ReferenceLibrary.1.0.0\lib\net461\ReferenceLibrary.dll</HintPath>
      <Private>True</Private>
    </Reference>
  </ItemGroup>

Update:

If we want to embed the DLLs for ReferenceLibrary inside Library1's nuget package, we should make sure the ReferenceLibrary.dll include in the Library1 package, No matter how we embed the DLLS. So you can add ReferenceLibrary.dll to the Library1.nuspec as file when we pack the Library1 package and set target to the lib folder. Below is my Library1.nuspec:

<?xml version="1.0"?>
<package >
  <metadata>
    <id>Library1</id>
    <version>1.0.0</version>
    <authors>xxxx</authors>
    <owners>xxxx</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Package description</description>
    <releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
    <copyright>Copyright 2017</copyright>
    <tags>Test</tags>
  </metadata>
     <files>
        <file src="..\Library1\bin\Debug\Referencelibrary.dll" target="\lib\net461" />
        <file src="..\Library1\bin\Debug\Library1.dll" target="\lib\net461" />
     </files>
</package>

Note that: You also need include the Library1.dll in the Library1.nuspec.

Solution 4

For placing DLLs within a folder of my choice I used the other customization point as described at Microsoft.

So I ended up with the following:

<PropertyGroup>
  <IncludeBuildOutput>false</IncludeBuildOutput> <!-- omit the package creating library itself -->
  <PackProject>true</PackProject>
  <TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);CreatePackNupkg</TargetsForTfmSpecificContentInPackage>
</PropertyGroup>

<Target Name="CreatePackNupkg">
  <ItemGroup>
    <TfmSpecificPackageFile Include="$(OutputPath)\<whatever>.*.dll">
      <PackagePath>folder/subfolder</PackagePath>
    </TfmSpecificPackageFile>
  </ItemGroup>    
</Target>

The NuGet.Pack package is created the same way (have a look).

Share:
17,208

Related videos on Youtube

Zorthgo
Author by

Zorthgo

Updated on June 21, 2022

Comments

  • Zorthgo
    Zorthgo almost 2 years

    I have a solution with two projects in it. First project is called Library1, which references project two called Referencelibrary. I am trying to embed the DLLs for ReferenceLibrary inside Library1's nuget package so that I don't have to publish 2 separate nuget packages. I've been able to embed ReferenceLibrary's DLL into the nuget package (so it seems) by adding the entries below into my csproj file:

      <ItemGroup>
        <ProjectReference Include="..\ReferenceLibrary\ReferenceLibrary.csproj">
            <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
            <IncludeAssets>ReferenceLibrary.dll</IncludeAssets>
            <IncludeAssets>ReferenceLibrary.pdp</IncludeAssets>
        </ProjectReference>
      </ItemGroup>
    

    But when I import the nuget package and try to run my test app, I get the following exception:

    Exception Screenshot I assumed that the DLLs had been embedded because prior to adding the "IncludeAssets" to the csproj, I wasn't able to import the nuget package because it was trying to reference the ReferenceLibrary nuget package. But after adding those entries, it allowed me to import it. But now it bombs at run-time. Any help would be greatly appreciated. Thanks!

    ;)

    • Jeroen Heier
      Jeroen Heier over 7 years
      "so that I don't have to publish 2 separate nuget packages": Why is this so important for you?
    • Weiwei
      Weiwei over 7 years
      Any update for this issue? Could you get useful information from Leo`s suggestion?
    • Zorthgo
      Zorthgo over 7 years
      Hi Jeroen, because I usually use a tiered approach for all of my code. Something that I often do is to separate my data access layer from the other layers. Therefore in this particular scenario, I don't want to publish a separate repository nuget package.
    • Zorthgo
      Zorthgo about 7 years
      @Wendy - MSFT - Not really, even after trying Leo's suggestion I am still getting the System.IO.FileNotFoundException error message.
  • Zorthgo
    Zorthgo over 7 years
    Hi Leo, thanks for the reply. I'll have to check this out when I get home later today. ;)
  • Zorthgo
    Zorthgo about 7 years
    I tried using the HintPath as you have above, but I am still getting the same System.IO.FileNotFoundException that I was getting before when running the .Net Core console application. :(
  • Leo Liu
    Leo Liu about 7 years
    @Zorthgo, I have updated my answer above, please check this when you free. If you have any update for this, please let me know. Hope this help you.
  • Zorthgo
    Zorthgo about 7 years
    Thanks for the update. I'll try this when I get home. One question though. You mentioned a .nuspec file, and on the example the target is set to "\lib\net461". I plan on creating .Net Standard libraries. So the package information is embedded in the .csproj file and no longer in a separate .nuspec file. Would the approach above also work with the new "dotnet pack" command? Thanks!
  • Leo Liu
    Leo Liu about 7 years
    @Zorthgo, According to this post and test by myself: github.com/dotnet/cli/issues/2170, "dotnet pack" by nupsec file is not supported. So I suggest you creating .Net Standard libraries using "nuget pack" command, please refer to docs.microsoft.com/en-us/nuget/guides/… for detail.
  • Neo
    Neo almost 5 years
    There is a more up-to-date workaround now commented at that issue on GitHub, which I've posted as an answer here.
  • JustAnotherDeveloper
    JustAnotherDeveloper over 4 years
    This works fine in terms of ensuring the required DLL end up in the lib folder of the nuget package, but now when consuming this package it looks for a nuget package with the name of the DLL, rather than using the one in the generated one.
  • viktor.kudria
    viktor.kudria over 4 years
    @JustAnotherDeveloper the reason of it is that your DLLs stil are in a resulted nuspec file, that are generated during packing. To fix it you have to add PrivateAssets="all" attribute to your project references (see the full example on github bi the link in the related answer).
  • Kiran
    Kiran almost 4 years
    Thank you! You saved me ton of time.
  • macwier
    macwier almost 4 years
    What if I have two ProjectReferences and want to keep one as nugget reference and inlcude the 2nd one?