Home: PackageRef project opt-in technique

Created on 3 Feb 2017  Â·  44Comments  Â·  Source: NuGet/Home

The issue is that transitive refs with PackageRef isn’t working with P2P refs between CPS and Legacy projects. With PackageRefs, this is supposed to be supported. 

So build the attached project. Try to run Net46ConsoleAppLegacy.exe. It throws due to a missing Newtonsoft.json. Look at the bindebug directory and you’ll see that the json ref is missing from the output.

By contrast, look at the Net46ConsoleAppCPS project and you’ll see that things work correctly.

There are a few issues in the legacy project:

  1. As you can see in the commented out code in Program.cs of Net46ConsoleAppLegacy, I cannot reference the bottom-most class library directly.
  2. I also cannot use a transitive NuGet reference there either.

Both of these work from the CPS version. This is very weird behavior to have a difference like this.

I get that P2P transitive refs are “new” for CPS, but transitive NuGet refs are not new and work today in VS 2015 with csproj+json. At the very least, I expect #2 to work and for the correct binaries to be in the output directory even if I cannot use types from ClassLibraryWithPackage in Net46ConsoleAppLegacy. The better scenario is that P2P should fully work here too and the Program.cs code in the CPS and Legacy version of the net46 exe should be the same.

SampleSolution.zip

Backlog 2 PackageReference Investigate DCR

Most helpful comment

This is going to be a very common scenario. People are creating new .NET Standard projects and will add p2p refs to them from their existing "legacy" projects. -- Xamarin, Desktop, etc.

The right binaries won't be in the output directory and people will be confused by this broken behavior.

The only workaround is that you have to add <RestoreProjectStyle>PackageReference</RestoreProjectStyle> to the legacy project.

All 44 comments

This is going to be a very common scenario. People are creating new .NET Standard projects and will add p2p refs to them from their existing "legacy" projects. -- Xamarin, Desktop, etc.

The right binaries won't be in the output directory and people will be confused by this broken behavior.

The only workaround is that you have to add <RestoreProjectStyle>PackageReference</RestoreProjectStyle> to the legacy project.

This user ran into it also: https://github.com/dotnet/sdk/issues/757#issuecomment-277152565

As another workaround if RestoreProjectStyle goes away is to use the following dummy packageref in the legacy csproj:

<PackageReference Include="Legacy2CPSWorkaround" Version="1.0.0">
  <PrivateAssets>All</PrivateAssets>
</PackageReference>

What do you mean if RestoreProjectStyle goes away? How would that happen?

It isn't going away for NetCore projects.
We had to remove reading it for non-cps scenarios for RTM.

@rrelyea Will there be a way to force a .NET Framework (non-CPS) project into PackageReference mode without actually adding a PackageReference item?

Another current workaround:
<PackageReference Update="PlaceholderToConvinceThisProjectToGetTransitivePackageReferenceFromProjectReferences"/>

@rrelyea does that placeholder have to exist? will there be restore errors/failures if it's not there?

I was just trying to find a workaround that involved a
<PackageReference />
When I tried it like above, it said you need include, remove or update.
Your workaround is to use include with a package that is a noop.
You can also do remove or update. I chose update as less confusing than remove, and somewhat self documenting.

Clearly, we want a more elegant solution.

Just wasn't sure with Update what happens if it tries to update a package that doesn't exist.

I think both remove and update are ok to do with package names that don't exist.

@rrelyea I tried the suggestion of using <PackageReference Update="Legacy2CpsWorkaroundBogus"/> and also <PackageReference Update="Legacy2CpsWorkaroundBogus" Version="1.0.0"/> but neither worked. Neither made the restore correct.

The only thing that's worked so far is to use:

    <PackageReference Include="Legacy2CPSWorkaround" Version="1.0.0">
      <PrivateAssets>All</PrivateAssets>
    </PackageReference>

Another report: dotnet/roslyn#17639

@jainaashish - We've been able to re-enable RestoreProjectStyle, in 4.1 already, right?

Yes, we've re-enabled RestoreProjectStyle property in 4.1

Reached out to unni to get PM owner for this issue.

Is there a workaround for VS2015 based solutions, or am I possibly doing something wrong? I used some of the workarounds above but it doesn't seem like my project files supports XML tags such as "RestoreProjectStyle". Currently I'm having to manually add nuget packages to my top-level win32 exe solutions every time I get a runtime error because of the missing dlls in the output directory. This type of error is terrifying to me as I have no good way of knowing if I'm missing a nuget reference in the top-level exe.

@jainaashish Is setting <RestoreProjectStyle>PackageReference</RestoreProjectStyle> the correct manual workaround for this scenario?

Will this be needed in 4.3/15.3 anymore or will it "just work" there?

@onovotny for now, this is the correct manual workaround. We haven't yet finalized the default opt-in experience for PackageReference but I'll let you know as soon as we have something there.

Is it just me or is this fixed with the newest Visual Studio Update 15.2 (26430.12)? I am able to remove the workaround.

I'd also like to know about possible workarounds or solutions for Visual Studio 2015. It's really bad to have exceptions at runtime because of Nuget-DLLs not found in the output path...

@Portikus same for me looks like they fix it.

@Portikus @mess285 Using 15.2, with a regular project referencing the CPS ones, it's not working for me without <RestoreProjectStyle>PackageReference</RestoreProjectStyle> being set. Is that what you are referring to?

@onovotny You are right. I tried your attached solution and it seems that it isn't fixed with the latest update. I'm sorry.

Do we have a roadmap on when this thing gets fixed? On the latest Preview Build of VS 2017 (Nuget 4.4.0.4453) , I am still seeing this problem.

Is this the same issue I'm seeing with Windows Runtime Components as well? Trying to reference Json.NET in a Windows Runtime Component used by a JavaScript based UWP project is throwing this error:

0x80070002 - JavaScript runtime error: The system cannot find the file specified.

System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified.

If I copy the dll into the AppX output though it works fine.

JSJSONTest.zip

Desktop project still having this problem in VS15.5

Have this issue with UWP project in VS15.5.6

I have the same problem in VS2017 with old csproj format. Does that mean that I can't use .NET Standard libraries (that has references) in .NET Framework projects? I thought that was the whole idea of .NET Standard :(

It is even worse -you do not even need an old style project.

I am writing a netstandard library that contains a powershell core module.

I can not debug or easily package it because it misses all references, among them entity framework core (and yes, this particular one needs db access).

What is the workaround in this case? I do not ahve an old style project - I only have one project, which is a nestandard 2.0 class library. I need all referenced assemblies in the folder.

I'm on the same boat as NetTecture, any solution?

I'm figuring out how to migrate a large MVC app. Right now, the plan had been to migrate all class libraries to .NET standard whilst leaving the MVC project in place in the old project format as an interim step. This issue appears to completely block us, unless anyone has a suggested workaround?

@jamescrowley this issue is more about file new project by default is old project format until you add a nuget package dependency which allows you to choose between new format vs old. And the workaround for that is to set RestoreProjectStyle to new format.

But your issue is different, you already have a bunch of old styled projects, and you're moving some of those to new format. Although partial migration might not give you all the advantages of new format but this should still work. What is failing for you in this case?

@jainaashish thanks for chiming in. Let me double check this again - may have been thrown off the scent by one of the other issues linking here.

Any update on this?

@anangaur do you have any update for this issue? Would love to get this in your planning...

Same issue. Update?

How on earth can this issue exist for over one and a half years? It makes using .net standard libraries in .net framework projects unusable.

@PaulVrugt I have no idea, but there are two workarounds I get along with.

  1. Build the package completely by yourself. (Without any generation) OR
  2. Build the package with VS and do not dare to save anything. Just create and upload 👍

Talked to @jainaashish and got enlightened on the scenario. Though the fix may seem non trivial for this issue this has repercussions on the VS experience where we show a popup dialogue to users to select the package format (PC vs. PR). Just added this to the list of PC --> PR issues @ https://github.com/NuGet/Home/issues/6659. We will be scheduling time to improve the PackageReference experiences and this should part of that.

Is this really still an issue without a solution?
I'm planning a migration to Core and Standard for a big application suite of 300+ projects, multiple web applications and desktop applications with shared code, but was planning on not migrating one of the WPF-apps.
Are there no workarounds?

Edit:
Got my prototype working with the Legacy2CPSWorkaround method. Is this still the preferred way to solve this?

Created a new solution with a WPF project and two .NET Standard projects. Getting the same issue where EF Core, System.Configuration.ConfigurationManager, etc. aren't found by the WPF project when used as dependencies in the .NET Standard projects

Edit: Added the <RestoreProjectStyle>PackageReference</RestoreProjectStyle> item directly under the first <PropertyGroup> in my .NET Framework 4.7.2 .csproj file. Solved the runtime error.

Per @rrelyea (this is rob typing) - let's spend a few hours this sprint (or soon) and discuss possible solutions and all aspects of the related problem - for new projects, old projects, etc...

Solved the same issue with the same workaround from @James-Lester with a .net 4.7.1 project referencing a .net standard 2.0 library.

Was this page helpful?
0 / 5 - 0 ratings