paquetes nuget .net-core .net-standard

nuget - paquetes - ¿Cuáles son las implicaciones de aplicación de una biblioteca netstandard dependiendo de un metapaquete?



nuget pack (3)

El equipo solía recomendar averiguar cuál era el conjunto de paquetes más delgado. Ya no hacen esto, y recomiendan que las personas solo traigan NETStandard.Library en su lugar (en el caso de un proyecto de estilo SDK, esto se hará automáticamente por usted).

Nunca he recibido una respuesta totalmente directa de por qué fue así, así que permítanme hacer algunas conjeturas fundamentadas.

Es probable que la razón principal sea que les permite ocultar las diferencias en las versiones de las bibliotecas dependientes que, de lo contrario, tendrían que rastrearse a sí mismos al cambiar los marcos de destino. También es un sistema mucho más fácil de usar con los archivos de proyecto basados ​​en SDK, porque francamente no necesita referencias para obtener una parte decente de la plataforma (al igual que solía hacerlo con las referencias predeterminadas en Desktop-land, especialmente mscorlib )

Al netstandard de lo que significa ser una biblioteca netstandard o una aplicación netcoreapp en el paquete NuGet apropiado, no tienen que desarrollar ningún conocimiento especial en la definición de esas cosas como Visual Studio (o dotnet new ) los ve

El análisis estático podría usarse durante la publicación para limitar las DLL enviadas, que es algo que hacen hoy cuando compilan de forma nativa para UWP (aunque con algunas advertencias). No lo hacen hoy para .NET Core, pero supongo que es una optimización que han considerado (además de admitir código nativo).

No hay nada que te impida ser muy selectivo, si así lo eliges. Creo que descubrirá que es casi el único que lo hace, lo que también frustra el propósito (ya que se supondrá que todo el mundo trae NETStandard.Library o Microsoft.NETCore.App ).

Supongamos que tengo una biblioteca de clases a la que quiero apuntar netstandard1.3, pero también uso BigInteger . Aquí hay un ejemplo trivial: el único archivo fuente es 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); } }

De vuelta en el mundo de project.json , apuntaría a netstandard1.3 en la sección de frameworks y tendría una dependencia explícita en System.Runtime.Numerics , por ejemplo, la versión 4.0.1. El paquete nuget que creo enumerará solo esa dependencia.

En el valiente y nuevo mundo de las herramientas de dotnet basadas en csproj (estoy usando v1.0.1 de las herramientas de línea de comandos) hay una referencia implícita de paquete de NETStandard.Library 1.6.1 a NETStandard.Library 1.6.1 cuando apunta a netstandard1.3 . Esto significa que mi archivo de proyecto es realmente pequeño, porque no necesita la dependencia explícita:

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

... pero el paquete nuget producido depende de NETStandard.Library , lo que sugiere que para usar mi pequeña biblioteca, necesita todo lo que necesita.

Resulta que puedo deshabilitar esa funcionalidad usando DisableImplicitFrameworkReferences , y luego agregar la dependencia manualmente nuevamente:

<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>

Ahora mi paquete NuGet dice exactamente de qué depende. Intuitivamente, esto se siente como un paquete "más delgado".

Entonces, ¿cuál es la diferencia exacta para un consumidor de mi biblioteca? Si alguien intenta usarlo en una aplicación para UWP, ¿la segunda forma de dependencias "recortadas" significa que la aplicación resultante será más pequeña?

Al no documentar DisableImplicitFrameworkReferences claramente (por lo que he visto; lo leí en un problema ) y al hacer que la dependencia implícita sea la predeterminada al crear un proyecto, Microsoft está alentando a los usuarios a que solo dependan del metapaquete, pero ¿cómo puedo hacerlo? asegúrese de que no tenga inconvenientes cuando produzca un paquete de biblioteca de clases?


En el pasado, les hemos dado a los desarrolladores la recomendación de no hacer referencia al NETStandard.Library ( NETStandard.Library ) de los paquetes NuGet, sino a paquetes individuales, como System.Runtime y System.Collections . La razón era que pensábamos en el metapaquete como una abreviatura de un conjunto de paquetes que eran los bloques de construcción atómicos reales de la plataforma .NET. La suposición era: podríamos terminar creando otra plataforma .NET que solo sea compatible con algunos de estos bloques atómicos, pero no con todos. Por lo tanto, cuantos menos paquetes haga referencia, más portátil será. También hubo preocupaciones con respecto a cómo nuestras herramientas se ocupan de los grandes gráficos de paquetes.

En el futuro, simplificaremos esto:

  1. .NET Standard es un bloque de construcción atómico . En otras palabras, a las nuevas plataformas no se les permite subconjuntar .NET Standard, tienen que implementarlo todo.

  2. Nos estamos alejando del uso de paquetes para describir nuestras plataformas , incluido .NET Standard.

Esto significa que ya no tendrá que hacer referencia a ningún paquete NuGet para .NET Standard. Expresó su dependencia con la carpeta lib, que es exactamente cómo ha funcionado para todas las demás plataformas .NET, en particular .NET Framework.

Sin embargo, en este momento nuestras herramientas aún se NETStandard.Library en la referencia a NETStandard.Library . No hay daño en eso tampoco, simplemente se volverá redundante en el futuro.

Actualizaré las FAQ en el repositorio de .NET Standard para incluir esta pregunta.

Actualización : esta pregunta ahora forma parte de las preguntas frecuentes .


No debería necesitar deshabilitar la referencia implícita. Todas las plataformas en las que la biblioteca podrá ejecutarse ya tendrán los ensamblados que NETStandard.Library dependencia NETStandard.Library .

.NET Standard Library es una especificación, un conjunto de ensamblados de referencia con los que compila que proporciona un conjunto de API que se garantiza que existen en un conjunto conocido de plataformas y versiones de plataformas, como .NET Core o .NET Framework . No es una implementación de estos ensamblados, solo la forma de API suficiente para permitir que el compilador construya con éxito su código.

La implementación de estas API es proporcionada por una plataforma de destino, como .NET Core, Mono o .NET Framework. Se envían con la plataforma, porque son una parte esencial de la plataforma. Por lo tanto, no es necesario especificar un conjunto de dependencias más pequeño: todo ya está allí, no lo cambiará.

El paquete NETStandard.Library proporciona estos ensamblados de referencia. Un punto de confusión es el número de versión: el paquete es la versión 1.6.1, pero esto no significa ".NET Standard 1.6". Es solo la versión del paquete.

La versión del estándar .NET al que se dirige proviene del marco de destino que especifique en su proyecto.

Si está creando una biblioteca y desea que se ejecute en .NET Standard 1.3, debe hacer referencia al paquete NETStandard.Library , actualmente en la versión 1.6.1. Pero lo más importante, su archivo de proyecto apuntaría a netstandard1.3 .

El paquete NETStandard.Library le dará un conjunto diferente de ensambles de referencia dependiendo de su nombre de marco de referencia (estoy simplificando por brevedad, pero piense en lib/netstandard1.0 , lib/netstandard1.1 y grupos de dependencia ). Entonces, si su proyecto apunta a netstandard1.3 , obtendrá los ensamblajes de referencia 1.3. Si apunta a netstandard1.6 , obtendrá los ensamblajes de referencia 1.6.

Si está creando una aplicación, no puede apuntar al estándar .NET. No tiene sentido: no puede ejecutar una especificación. En su lugar, apunta a plataformas concretas, como net452 o netcoreapp1.1 . NuGet conoce el mapeo entre estas plataformas y los netstandard framework de destino netstandard, así que sabe qué carpetas lib/netstandardX.X son compatibles con su plataforma de destino. También sabe que las dependencias de NETStandard.Library son satisfechas por la plataforma de destino, por lo que no atraerá ningún otro ensamblado.

Del mismo modo, al crear una aplicación .NET Core independiente, los ensamblados de implementación de .NET Standard se copian con su aplicación. La referencia a NETStandard.Library no NETStandard.Library ninguna otra aplicación nueva.

Tenga en cuenta que dotnet publish creará una aplicación independiente , pero actualmente no lo hará, y publicará todos los ensamblajes. Esto se manejará automáticamente con herramientas , por lo que nuevamente, el recorte de dependencias en su biblioteca no ayudará aquí.

El único lugar que puedo imaginar donde podría ayudar a eliminar el NETStandard.Library referencia es si está apuntando a una plataforma que no es compatible con el estándar .NET, y puede encontrar un paquete desde el estándar .NET donde todos los transitivos las dependencias pueden ejecutarse en su plataforma de destino. Sospecho que no hay muchos paquetes que se ajusten a esa factura.