sdk: Dependencies don't flow from new NETStandard project to old Desktop projects through ProjectReferences

Copied from https://github.com/dotnet/corefx/issues/14565.

From @jnm2

Am I doing something incorrect? I was not sure if this is the same problem as the other problems I’ve had with netstandard. Just by luck, every single one of my forays into netstandard have failed with this same type of issue. I have great confidence that it’s just me and these will all be fixed by VS2017’s RTM.

Create a new .NET Standard library targeting netstandard1.3. Create a static method Class1.DoWork() that throws new Win32Exception(). Add a .NET Framework console app targeting net462 In Program.cs, call Class1.DoWork() and add a reference to the library project. Run the console app and get:

System.IO.FileNotFoundException occurred
HResult=0x80070002
Message=Could not load file or assembly 'Microsoft.Win32.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
Source=NetstandardLibrary
StackTrace:
at NetstandardLibrary.Class1.Works() in C:\Users\Joseph\documents\visual studio 2017\Projects\NetstandardOnDesktop\NetstandardLibrary\Class1.cs:line 10
at DesktopConsoleApp.Program.Main(String[] args) in C:\Users\Joseph\documents\visual studio 2017\Projects\NetstandardOnDesktop\DesktopConsoleApp\Program.cs:line 9

Is this a binding redirect issue or something? I hope this isn’t the way things are intended to be? As long as this type of error exists, can you please maintain a netstandard troubleshooting document with step-by-step guidance for the workaround?

I would hope that scenarios like this would be covered by integration tests.

https://github.com/jnm2/misc-codesamples/raw/master/Bug reports/.NET/NetStandard Win32Exception causes file not found.zip

From @weshaggard

Looking at his solution the issue stems from the fact that the ProjectReference from the DesktopConsoleApp to the NETStandardLibrary project isn’t flowing the dependencies correctly so it isn’t seeing Microsoft.Win32.Primitives at all. It isn’t even an issue with binding redirects in this case it is just a missing dependency. To workaround it you can add a reference to the Microsoft.Win32.Primitives nuget package to the DesktopConsoleApp. However this sounds like a tooling issue where dependencies aren’t flowing.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 6
  • Comments: 48 (16 by maintainers)

Commits related to this issue

Most upvoted comments

For anyone that might still be hitting this you can workaround it by explicitly making the .NET Framework project a ProjectReference based project by setting the following property in the project:

<RestoreProjectStyle>PackageReference</RestoreProjectStyle>

There is also a good change you will need auto-bindingredirects as well so make sure that is set in your project:

<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>

@davidfowl So what’s the long term solution here? Using the PackageReference solution? Googling about this problem reveals a lot of confusion around this behavior, and the documentation could be more clear (unless I’m missing some important docs).

Please help me understand a bit more.

Console App (.NET 4.6.1) -> Class Library 1 (.NET 4.6.1) -> Class Library 2 (.NET Standard 2.0) -> NuGet Package (Newtonsoft.Json)

After build, the Console App’s bin directory contains:

  • Console App.exe
  • Class Library1.dll

This will fail at runtime because Class Library 2.dll and Newtonsoft.Json.dll are non-existent.

The Visual Studio tooling seems to offer no assistance to remedy this unless I’m missing something.

Can we just don’t break .NET Framework projects introducing half done (like .NET Core) style features?

My .net framework 4.7 project already has the package references in the project file. I also tried adding the <RestoreProjectStyle>PackageReference</RestoreProjectStyle> and <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> But I’m still running into the FileNotFound exception as soon as I access code from the .net standards class library. I’m missing the references the class library depends on.

I have experienced this same issue, but the workaround didn’t seem to resolve the problem in my case. Here are some steps to reproduce a simple version of what I’m seeing:

  1. Create a new solution. Add a new NetStandard class library project to it.
  2. Add a new ASP.NET Web Application project to the same solution - select “Web API” as the template.
  3. Add the class library project to the web application project as a project reference.
  4. Add the “System.Data.SqlClient” Nuget package to the class library project…
  5. Add this class to the class library project:
using System.Data.SqlClient;

namespace ClassLibrary1 {
  public class Class1 {
    public Class1() {
      var connection = new SqlConnection("");
    }
  }
}
  1. At the end of the Global.asax file in the web application project root, add the following line:
var c = new ClassLibrary1.Class1();
  1. Run the web application project. It crashes on startup at the line above with the following error:

System.IO.FileNotFoundException: ‘Could not load file or assembly ‘System.Data.SqlClient, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ or one of its dependencies. The system cannot find the file specified.’

Not sure if it’s something specifically to do with how web application projects resolve dependencies, but adding the RestoreProjectStyle and AutoGenerateBindingRedirects to the project file didn’t fix the issue.

The only way I could work around the problem was to install all the dependencies in both projects.

This works for project references for the project in the same solution. If I try to add a reference to an external project .dll from a project in another solution, that project’s dependencies don’t get copied into the output folder of the referring project.

@weshaggard - does PackageReference just happen to work with .NET Framework projects? The doc you linked suggests it’s not supported:

At present, package references are supported in Visual Studio 2017 only, for .NET Core projects, .NET Standard projects, and UWP projects targeting Windows 10 Build 15063 (Creators Update).

There are two ways to fix this:

  • Install all dependencies in your .NET Framework project
  • Migrate the .NET Framework project to PackageReference
    • If your .NET Framework project doesn’t reference any packages, then add the following property to your project file: <RestoreProjectStyle>PackageReference</RestoreProjectStyle>

Still got the problem in VS2017 15.5 , .NET Framework 4.6.1 and Core 2.0 Standard 1.4 Yet solved by <PropertyGroup> <TargetFramework>netstandard1.4</TargetFramework> <RestoreProjectStyle>PackageReference</RestoreProjectStyle> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> </PropertyGroup>

The ideal scenario is that the class library is netstandard*.* and the test project targets net***;netcoreapp*.* or something like that. If you make the class library target both netstandard1.4 and net461, you won’t be truly testing the netstandard1.4 dll because the test project will ignore it and pick up the net461 dll.

Have you tried adding a net461 target to the standard library? That fixed it for me.

I’m using VS2017 15.3.3 and .NET Core 2.0.0 SDK. My (simplified) solution consists of following projects:

  • Project A - .NET Standard 2.0 class library; referencing Newtonsoft.Json via Nuget
  • Project B - .NET 4.6.1 WPF; referencing A
  • Project C - .NET 4.6.1 unit test project; referencing A

Using <RestoreProjectStyle>PackageReference</RestoreProjectStyle> fixed the problem in B. But when I applied it to C, suddenly all tests disappeared from Test Explorer window. To fix this issue, I had to upgrade test adapters and test framework via nuget as described here (in case somebody has the same problem).

Is this intended behavior of package reference or a bug?

I think I’m seeing the same thing with a JavaScript UWP app, as the default VS template uses package.json for those projects.

Referencing a .NET Standard 1.4 component using ProjectReference through a Windows Runtime Component.

@babelshift SDK projects don’t copy dependencies to the output directory because the output can be different depending on what the TFM of the consuming project is. Consider the following:

A (project) (net461) B (project) (netstandard 2.0) Newtonsoft.Json (package) (net45, ns1.1)

A -> B -> Newtonsoft.Json

For this dependency graph, the version of Newtonsoft.Json copied to A’s output folder is net45, the version copied into the output of B is ns1.1

Adding <PropertyGroup> <RestoreProjectStyle>PackageReference</RestoreProjectStyle> </PropertyGroup> to the project file for the classic project made it indeed work. Still strange , because this was already the format for the project… Oh well… Thanks for the help