How to restore assemblies from a NuGet package for a specific target framework only

2.2k Views Asked by At

I'm looking for a way to restore the assemblies for a NuGet package which targets exactly one framework, in this case net45.

This is my packages config:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Newtonsoft.Json" version="12.0.1" targetFramework="net45" />
</packages>

This is my NuGet config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <config>
        <add key="repositoryPath" value=".\Nuget" />
    </config>
</configuration>

Version is: NuGet Version: 5.2.0.6090

Running: nuget restore packages.config -ConfigFile nuget.config restores the assemblies for all targetframework versions as can be seen by:

E:\Tmp\NuGet\Nuget\Newtonsoft.Json.12.0.1>dir lib
 Directory of E:\Tmp\NuGet\Nuget\Newtonsoft.Json.12.0.1\lib

2019-09-30  18:27    <DIR>          .
2019-09-30  18:27    <DIR>          ..
2019-09-30  18:27    <DIR>          net20
2019-09-30  18:27    <DIR>          net35
2019-09-30  18:27    <DIR>          net40
2019-09-30  18:27    <DIR>          net45
2019-09-30  18:27    <DIR>          netstandard1.0
2019-09-30  18:27    <DIR>          netstandard1.3
2019-09-30  18:27    <DIR>          netstandard2.0
2019-09-30  18:27    <DIR>          portable-net40+sl5+win8+wp8+wpa81
2019-09-30  18:27    <DIR>          portable-net45+win8+wp8+wpa81

According to learn.microsoft.com

When NuGet installs a package that has multiple assembly versions, it tries to match the framework name of the assembly with the target framework of the project.

If a match is not found, NuGet copies the assembly for the highest version that is less than or equal to the project's target framework, if available. If no compatible assembly is found, NuGet returns an appropriate error message.

For example, consider the following folder structure in a package:

\net45
  \MyAssembly.dll
\net461
  \MyAssembly.dll 

When installing this package in a project that targets .NET Framework 4.6, NuGet installs the assembly in the net45 folder, because that's the highest available version that's less than or equal to 4.6.

If the project targets .NET Framework 4.6.1, on the other hand, NuGet installs the assembly in the net461 folder.

From the paragraph above I understand that when I set the target framework I should be able to restore just the assemblies for that one target framework. In my case it looks like NuGet completely ignores the targetFramework attribute and always installs the dlls for all target frameworks. Changing it from net45 to net40 has no effect.

How can I make NuGet restore ONLY the dlls in a package for a specific target framework?

3

There are 3 best solutions below

1
Guilherme Martin On

Try to change your targetFramework from

targetFramework="net45"

to

targetFramework="4.5"
2
Michael Blake On

I don't think you can.

Fiddler

The nuget (zip) contains all the frameworks.

All Nuget.exe is doing is downloading the file and extracting it. You could delete the ones you don't want afterwards?

Also, why not just use .\nuget.exe restore -Force -NoCache -Packagesdirectory .\Nuget instead of the nuget config file?

You could confuse people by creating your own package that just contains your framework!

0
Cirdec On

For unity, you can configure which .dll version to use for which platforms with the *.dll.meta files.

Get the packages

Specify where to put the packages either on the command line or in a nuget.config file so that they will be included as assets in unity.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <config>
      <add key="globalPackagesFolder" value="./NuGetPackages" />
  </config>
</configuration>

If you use packages.config set the repositoryPath instead of the globalPackagesFolder.

This can go in the same folder as your dotnet solution, in which case you can restore the packages with dotnet restore or nuget restore in the solution folder.

Configure which version is used in Unity

Find the dll files from the package

Unity dll file from a nuget package

Open the file in the inspector and disable it for platforms, or conditionally for build constraints.

Unity dll inspector with all platforms disabled

This gets saved into the .dll.meta files in the same directory as the .dll. You don't want them to be deleted so ...

Configure source control to keep the .dll.meta files

This .gitignore will exclude everything from the packages, but will keep the .dll.meta files that specify which version Unity uses.

**/NuGetPackages/**
!**/NuGetPackages/**/
!**/NuGetPackages/**/*.dll.meta