Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the application implications of a netstandard library depending on a metapackage?

Suppose I have a class library which I want to target netstandard1.3, but also use BigInteger. Here's a trivial example - the sole source file is Adder.cs:

using System; using System.Numerics;  namespace Calculator {     public class Adder     {         public static BigInteger Add(int x, int y)             => new BigInteger(x) + new BigInteger(y);                 } } 

Back in the world of project.json, I would target netstandard1.3 in the frameworks section, and have an explicit dependency on System.Runtime.Numerics, e.g. version 4.0.1. The nuget package I create will list just that dependency.

In the brave new world of csproj-based dotnet tooling (I'm using v1.0.1 of the command-line tools) there's an implicit metapackage package reference to NETStandard.Library 1.6.1 when targeting netstandard1.3. This means that my project file is really small, because it doesn't need the explicit dependency:

<Project Sdk="Microsoft.NET.Sdk">   <PropertyGroup>     <TargetFramework>netstandard1.3</TargetFramework>   </PropertyGroup> </Project> 

... but the nuget package produced has a dependency on NETStandard.Library, which suggests that in order to use my small library, you need everything there.

It turns out I can disable that functionality using DisableImplicitFrameworkReferences, then add in the dependency manually again:

<Project Sdk="Microsoft.NET.Sdk">       <PropertyGroup>     <TargetFramework>netstandard1.3</TargetFramework>     <DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>   </PropertyGroup>    <ItemGroup>     <PackageReference Include="System.Runtime.Numerics" Version="4.0.1" />   </ItemGroup>     </Project> 

Now my NuGet package says exactly what it depends on. Intuitively, this feels like a "leaner" package.

So what's the exact difference for a consumer of my library? If someone tries to use it in a UWP application, does the second, "trimmed" form of dependencies mean that the resulting application will be smaller?

By not documenting DisableImplicitFrameworkReferences clearly (as far as I've seen; I read about it in an issue) and by making the implicit dependency the default when creating a project, Microsoft are encouraging users to just depend on the metapackage - but how can I be sure that doesn't have disadvantages when I'm producing a class library package?

like image 256
Jon Skeet Avatar asked Mar 22 '17 09:03

Jon Skeet


People also ask

What is Netstandard library?

NET Standard allows a library to use more APIs but means it can only be used on more recent versions of . NET. Targeting a lower version reduces the available APIs but means the library can run in more places.

Is .NET 6 compatible with .NET standard 2?

2 Answers. According to this document, . NET 6 supports . NET Standard 2.1.

Is .NET standard compatible with .NET 6?

It can be installed on linux/mac/windows. NET Standard is a set of interfaces that help to guarantee cross-compatibility no matter whether you are running NET Framework or NET 5/6/7. Targeting Netstandard 2.0 or lower means you'll be able to run on NET 5/6/7 or NET Framework 4.

Is .NET standard 2.1 compatible with .NET framework?

You cannot consume a . Net Standard 2.1 assembly in any . Net Framework Version because the . NET Framework (even the last ever version, 4.8) does not implement .


1 Answers

In the past, we've given developers the recommendation to not reference the meta package (NETStandard.Library) from NuGet packages but instead reference individual packages, like System.Runtime and System.Collections. The rationale was that we thought of the meta package as a shorthand for a bunch of packages that were the actual atomic building blocks of the .NET platform. The assumption was: we might end up creating another .NET platform that only supports some of these atomic blocks but not all of them. Hence, the fewer packages you reference, the more portable you'd be. There were also concerns regarding how our tooling deals with large package graphs.

Moving forward, we'll simplify this:

  1. .NET Standard is an atomic building block. In other words, new platforms aren't allowed to subset .NET Standard -- they have to implement all of it.

  2. We're moving away from using packages to describe our platforms, including .NET Standard.

This means, you'll not have to reference any NuGet packages for .NET Standard anymore. You expressed your dependency with the lib folder, which is exactly how it has worked for all other .NET platforms, in particular .NET Framework.

However, right now our tooling will still burn in the reference to NETStandard.Library. There is no harm in that either, it will just become redundant moving forward.

I'll update the FAQ on the .NET Standard repo to include this question.

Update: This question is now part of the FAQ.

like image 184
Immo Landwerth Avatar answered Sep 29 '22 15:09

Immo Landwerth