Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Application targeting net462 imports library targeting net451 instead of library targeting netstandard2.0 #5370

Closed
nguerrera opened this issue Jun 8, 2017 · 5 comments

Comments

@nguerrera
Copy link

From @caleblloyd on June 8, 2017 1:24

Steps to reproduce

  1. Build a class library with target frameworks:
<TargetFrameworks>net451;netstandard1.3;netstandard2.0</TargetFrameworks>
  1. Build an application that imports the class library with target frameworks:
net46;net462;netcoreapp1.1.2;netcoreapp2.0
  1. Run dotnet restore

Expected behavior

  • App net46 should import library net451
  • App net462 should import library netstandard2.0
  • App netcoreapp1.1.2 should import library netstandard1.3
  • App netcoreapp2.0 should import library netstandard2.0

Actual behavior

All of the above are true except for App net462 imports library net451. Since net462 supports netstandard2.0, and netstandard2.0 is newer than net451, shouldn't the app targeting net462 import the library targeting netstandard2.0 instead?

Here is the pruned obj/project.assets.json:

{
  "version": 2,
  "targets": {
    ".NETCoreApp,Version=v1.1.2": {
      ...,
      "MySqlConnector/0.20.1": {
        "type": "project",
        "framework": ".NETStandard,Version=v1.3",
        "dependencies": {
          "NETStandard.Library": "1.6.1",
          "System.Buffers": "4.3.0",
          "System.Data.Common": "4.3.0",
          "System.Net.NameResolution": "4.3.0",
          "System.Net.Security": "4.3.0",
          "System.Threading.Tasks.Extensions": "4.3.0"
        },
        "compile": {
          "bin/placeholder/MySqlConnector.dll": {}
        },
        "runtime": {
          "bin/placeholder/MySqlConnector.dll": {}
        }
      }
    },
    ".NETCoreApp,Version=v2.0": {
      ...,
      "MySqlConnector/0.20.1": {
        "type": "project",
        "framework": ".NETStandard,Version=v2.0",
        "dependencies": {
          "System.Buffers": "4.3.0",
          "System.Data.Common": "4.3.0",
          "System.Net.NameResolution": "4.3.0",
          "System.Net.Security": "4.3.0",
          "System.Threading.Tasks.Extensions": "4.3.0"
        },
        "compile": {
          "bin/placeholder/MySqlConnector.dll": {}
        },
        "runtime": {
          "bin/placeholder/MySqlConnector.dll": {}
        }
      }
    },
    ".NETFramework,Version=v4.5.1": {
      ...,
      "MySqlConnector/0.20.1": {
        "type": "project",
        "framework": ".NETFramework,Version=v4.5.1",
        "dependencies": {
          "System.Buffers": "4.0.0",
          "System.Runtime.InteropServices.RuntimeInformation": "4.0.0",
          "System.Threading.Tasks.Extensions": "4.0.0"
        },
        "compile": {
          "bin/placeholder/MySqlConnector.dll": {}
        },
        "runtime": {
          "bin/placeholder/MySqlConnector.dll": {}
        }
      }
    },
    ".NETFramework,Version=v4.6.2": {
      ...,
      "MySqlConnector/0.20.1": {
        "type": "project",
        "framework": ".NETFramework,Version=v4.5.1",
        "dependencies": {
          "System.Buffers": "4.0.0",
          "System.Runtime.InteropServices.RuntimeInformation": "4.0.0",
          "System.Threading.Tasks.Extensions": "4.0.0"
        },
        "compile": {
          "bin/placeholder/MySqlConnector.dll": {}
        },
        "runtime": {
          "bin/placeholder/MySqlConnector.dll": {}
        }
      }
    }
  },
  "libraries": {
 	...
  }
}

Environment data

$ dotnet --info
.NET Command Line Tools (2.0.0-preview1-005977)

Product Information:
 Version:            2.0.0-preview1-005977
 Commit SHA-1 hash:  414cab8a0b

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  17.04
 OS Platform: Linux
 RID:         ubuntu.16.04-x64
 Base Path:   /usr/share/dotnet/sdk/2.0.0-preview1-005977/

Microsoft .NET Core Shared Framework Host

  Version  : 2.0.0-preview1-002111-00
  Build    : 1ff021936263d492539399688f46fd3827169983

Copied from original issue: dotnet/cli#6798

@nguerrera
Copy link
Author

nguerrera commented Jun 8, 2017

I believe this is by design in terms of precedence. Same target framework identifier is considered "nearer" than compatible identifier.

@emgarten
Copy link
Member

emgarten commented Jun 8, 2017

I believe this is by design in terms of precedence. Same target framework identifier is considered "nearer" than compatible identifier.

This is correct. Desktop frameworks win over non-desktop frameworks. NuGet tries to find the largest compatible API surface area.

@caleblloyd
Copy link

Should this change with netstandard2.0?

Lots of libraries maintain net45 to support Windows Server 2012. But netstandard2.0 contains more APIs and it seems like that should be preferred for net461 and up. Otherwise library maintainers would have to additionally publish a net461 package to get these new APIs on desktop.

@emgarten
Copy link
Member

Otherwise library maintainers would have to additionally publish a net461 package to get these new APIs on desktop.

An additional package is not needed, authors can add net461 or net47 to the same package.

But netstandard2.0 contains more APIs and it seems like that should be preferred for net461 and up

If for example the project is net47 and the package contains net47 and netstandard2.0 the user should still get net47, the desktop framework is an identical match.

In the case of net45 vs netstandard2.0 there are APIs that are available in net45 that are not in netstandard2.0, NuGet can't determine exactly which is going to be a better match for the user so it leaves it up to the package author. Authors can rely on NuGet to favor a match within the same framework, and can add support for higher versions of it if they are actually using APIs beyond the net45 API surface area.

@caleblloyd
Copy link

Since this is working as designed it should be OK to close then. Thanks for explaining why Desktop is preferred over netstandard in NuGet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants