7

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?

Bobby Tables
  • 2,953
  • 7
  • 29
  • 53
  • Why is this important to you? What do you want to achieve? If you just want the assemblies relevant to your project, when you build your project, the bin directory will contain all the assembies since you target a .NET Framework TFM. With .NET Core projects, you can use `dotnet publish`. – zivkan Oct 04 '19 at 03:02
  • 1
    @zivkan unfortunately I'm using it with Unity which throws an error when it finds multiple dlls with the same name. The problems is that according to the MS docs it should be working but it's not. – Bobby Tables Oct 04 '19 at 11:40

3 Answers3

0

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!

Michael Blake
  • 2,068
  • 2
  • 18
  • 31
  • I'm using the nuget.config file because it also contains some custom repositories which are internal. Deleting the ones which I don't need is what I'm doing now, via powershell but I'm looking for a way to do that automatically and based on **my** understainding of the the docs it should be working. Also I know that the packages contains all of versions of an assembly but the I don't understand what's the point of the target framework – Bobby Tables Oct 09 '19 at 13:03
  • Fair enough about about the config, i was basing it on you example. Check https://learn.microsoft.com/en-us/nuget/reference/packages-config#schema . It's not to filter them, it's use to know if the project has been upgraded and therefore references are old. It warns if the csproj doesn't match the package.config. You could also consider using the new csproj format if unity support it. – Michael Blake Oct 09 '19 at 13:12
0

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
Cirdec
  • 24,019
  • 2
  • 50
  • 100
-3

Try to change your targetFramework from

targetFramework="net45"

to

targetFramework="4.5"
Guilherme Martin
  • 837
  • 1
  • 11
  • 22
  • Thanks for the answer but unfortunately "4.5" is not a valid TFM, here's the list of possible options https://learn.microsoft.com/en-us/nuget/reference/target-frameworks#supported-frameworks – Bobby Tables Oct 04 '19 at 11:42