1

Question:

How to manage nuget packages in a VisualStudio2017 solution with 3 platforms:

  • .Net Standard 1.3
  • .Net Framework 4.6
  • .Net Core 1.0

?

I like the PackageReference approach, but i don't know how to use it. They talk about:

<ItemGroup>
    <!-- ... -->
    <PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
    <!-- ... -->
</ItemGroup>
  • Does it mean that in general i need at least 3 PackageReferences for each of Framework/Standard/Core?
  • How to manage the versions when we are stuck with .Net Framework 4.6?
  • I also ran across the issue when i could not run a console .net core app referencing .net standard lib due to nuget versions compatibility problem.

In addition, i'd like to mention that i came across a couple of articles that stated that .csprojs are back and there's no need of .xproj, project.json. Personally, i like this idea to deal with .csprojs like previously.


Context:

I'm not a native English speaker and i'm very new to non-trivial nuget usages and .Net Core/Standard development.

I'm preparing to port a .Net Framework application to .Net Framework+Standard+Core. This is now just a WPF application. But in the future it's intended to stay the same WPF app, but also to have a new .Net Core branch, raising from the existing logic. I don't know exactly what the plans are for the possible new .Net Core branch. Most probably, the plans are to create an ASP.Net Core website. What i know for sure is that the task is to keep logic running as .Net Framework (with WPF UI) and also get it implemented as .Net Core.

I decided to use the combination of Framework+Standard+Core as the solution because of its simplicity. I mean that the conception is easy to understand: base classes (standard) used by 2 brances (FWK, Core). No need of mutitargeting or directives in code (conditional compilation). Implying that the new solution should be created from scratch by copy-pasting and modifying. Still not 100% sure about the reasonability of this decision.

But the question implies that this very approach is to be taken: Framework+Standard+Core.


I hope taht this question is reasonable; i mean that the effective managing of nuget packages in such case is a good start for a successfull cross-platform project. Thanks!

Andrey K.
  • 665
  • 8
  • 29
  • 1
    When you are stuck on .NET Framework 4.6, do create a multi-targeting core library for `net46` and `netstandard20`. It is meaningless to target `netstandard13` as the API there is very limited, and you don't need to support legacy platforms like WP or Silverlight. Do your experiments with `PackageReference` and you don't even need to ask first questions. What exactly is the issue of "I also ran across the issue when i could not run a console .net core app referencing .net standard lib due to nuget versions compatibility problem"? – Lex Li Jul 20 '18 at 12:16
  • @LexLi it isn't "meaningless" - it just isn't typically useful unless you're actively trying to target some downlevel frameworks such as windows phone – Marc Gravell Jul 20 '18 at 12:17
  • @LexLi, thanx a lot! probably it's a good idea to do multitargeting. As for versions compatibility problem: i could not run a netcore1.0 console app referencing netstandard1.3 lib in vs17 (see next comment). Thanks! – Andrey K. Jul 20 '18 at 13:06
  • @LexLi, Output: The program '[12780] dotnet.exe' has exited with code -2147450751 (0x80008081). The program '[1996] iisexpress.exe' has exited with code 0 (0x0). – Andrey K. Jul 20 '18 at 13:07

1 Answers1

3

Note: I'm assuming that you're using the new SDK csproj format here, and something like:

<TargetFrameworks>netstandard1.3;net46;netcoreap1.0</TargetFrameworks>

If the thing that you're referencing exists and targets all the same platforms as your project, it should just work. However, unless you're actually doing something different in Framework vs Standard vs Core, you might as well just target Standard, and in reality: many libs are now rebasing against netstandard2.0 as the minimum. This may or may not be possible for you.

Versions don't work any differently on 4.6, unless there are problems with specific packages, but: you can get around that by using Condition attributes on the <ItemGroup> or on specific <PackageReference> elements. For example, I have a library that targets net461 and netstandard2.0; and as it happens, everything I'm using is already built into net461, so to avoid having any downstream dependencies, I can do:

  <ItemGroup Condition="'$(TargetFramework)'=='net461'">
    <Reference Include="Microsoft.CSharp" />
  </ItemGroup>
  <ItemGroup Condition="'$(TargetFramework)'!='net461'">
    <PackageReference Include="System.Data.Common" Version="4.3.0" />
    <PackageReference Include="System.Reflection" Version="4.3.0" />
    <PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
    <PackageReference Include="System.Reflection.Emit.ILGeneration" Version="4.3.0" />
    <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.0" />
    <PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
    <PackageReference Include="System.Security.Permissions" Version="4.5.0" />
  </ItemGroup>

This gives me (in nuget):

enter image description here

however; I could have left everything as just:

  <ItemGroup>
    <PackageReference Include="System.Data.Common" Version="4.3.0" />
    <PackageReference Include="System.Reflection" Version="4.3.0" />
    <PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
    <PackageReference Include="System.Reflection.Emit.ILGeneration" Version="4.3.0" />
    <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.0" />
    <PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
    <PackageReference Include="System.Security.Permissions" Version="4.5.0" />
  </ItemGroup>

and it would have worked fine - just : the net461 target would list dependencies. I could also have listed completely different dependencies per target framework.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900