Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When using nuget packages is there a way to avoid netstandard assemblies in favor of PCL?

I have a desktop application and a simple class library that targets the .Net framework 4.6.2. Recently I noticed that when I update my nuget packages in VS 2017 (15.6.3), one of them started pulling in the some newer netstandard2.0 assemblies.

I'm eager to build netstandard libraries some day. But for now I'd prefer it if the corresponding PCL (available within the same nuget package) would be introduced into my project as a dependency instead of the netstandard assembly. The nuget PCL assembly which I'm after targets "portable-net45+win8+wp8+wpa81".

The reason I don't want a netstandard2.0 assembly is because it causes a bunch of shim assemblies to appear in the output directory and this is overkill given that my application class library itself doesn't target netstandard2.0. Another thing that happens is VS starts generating a bunch of version conflicts (warnings in compiler output) for unrelated packages like System.ValueTuple. This appears to be shim-related as well (the shims are probably coming from the path C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib)

Below is a sample of the version conflicts that I've started seeing.

Encountered conflict between 'Reference:System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL' and 'Reference:System.ValueTuple'. Choosing 'Reference:System.ValueTuple' because file version '4.6.26011.1' is greater than '4.6.25519.3'.

I expect these are just warnings, albeit very scary ones. I believe these are just file version problems (not related to assembly versions), and don't think they will result in any need for binding redirects. Even so, I'd be much happier to go back to my PCL's again and avoid all of this stuff. I think I'll be more eager to use and build netstandard assemblies once the .Net Framework 4.7.2 is released.

I'm using the old-school csproj format and packages.config for nuget. The nuget dependency that seems to bring in the netstandard2.0 bits is System.Composition.

System.Composition  1.1.0
System.Composition.AttributedModel  1.1.0
System.Composition.Convention   1.1.0
System.Composition.Hosting  1.1.0
System.Composition.Runtime  1.1.0
System.Composition.TypedParts   1.1.0
System.ValueTuple   4.4.0

Hope this is clear. My workaround at this time is to create another class library that targets .Net 4.5, introduce the System.Composition nuget dependency, run update-package, and then copy/paste the packages references from the .Net 4.5 csproj to the .Net 4.6.2 project. Then I have to remember to avoid updating my packages on that .Net 4.6.2 project or it will overwrite my references to the PCL assemblies.

I'd greatly appreciate any help. I spent a couple hours playing with nuget update commands and haven't found the trick to avoiding netstandard yet. The closest I got was to use "TargetFrameworks" in the csproj instead of "TargetFrameworkVersion" but ran into trouble with that as well.

like image 634
David Beavon Avatar asked Nov 07 '22 09:11

David Beavon


1 Answers

When using nuget packages is there a way to avoid netstandard assemblies in favor of PCL?

This is a known issue for .net 4.6.2 and 4.7.1, which needs a few of these system.* assemblies since there is a bug in 4.7.1, when you update some nuget packages to the latest version, some of them may pull the newer netstandard2.0 assembly.

If you do not want add those netstandard assemblies, you can targets to .net 4.7.1, but it still needs 12 of them and on .net 4.7.2, the bin folder will only contain your dlls and pdbs. For some more detailed info you can refer to following thread:

net462 referencing netstandard2.0 - can the large number of dlls be avoided?

Actually 4.7.1 will also need a few shims in order to be able to load .netstandard2.0 assemblies, but there are only 12 needed and with the tooling that we are about to release these are the only ones that will be copied to the bin folder. On 4.7.2, compatibility with netstandard will be inbox which means that if you retarget your app for 4.7.2 (once that is avaliable) the bin folder will only contain your dlls and pdbs.

In 4.6.2 you still need the shims there because that is the way your netstandard library will be able to bind to the desktop runtime.

.NET Standard issues on .NET Framework 4.7.1

Hope this helps.

like image 88
Leo Liu-MSFT Avatar answered Nov 29 '22 19:11

Leo Liu-MSFT