Supongamos que tengo una biblioteca de clases que quiero apuntar a netstandard1.3, pero también usar 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 netstandard1.3
en la frameworks
sección y tendría una dependencia explícita System.Runtime.Numerics
, por ejemplo, la versión 4.0.1. El paquete nuget que creo enumerará solo esa dependencia.
En el valiente nuevo mundo de las herramientas dotnet basadas en csproj (estoy usando la v1.0.1 de las herramientas de línea de comandos) hay una referencia implícita de paquete de metapaquete a la NETStandard.Library 1.6.1
hora de apuntar 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 tiene una dependencia de NETStandard.Library
, lo que sugiere que para usar mi pequeña biblioteca, necesita todo lo que está allí.
Resulta que puedo deshabilitar esa funcionalidad usando DisableImplicitFrameworkReferences
, 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 "recortada" significa que la aplicación resultante será más pequeña?
Al no documentar DisableImplicitFrameworkReferences
claramente (por lo que he visto; leí sobre esto en un número ) y al hacer que la dependencia implícita sea la predeterminada al crear un proyecto, Microsoft está animando a los usuarios a depender simplemente del metapaquete, pero ¿cómo puedo hacerlo? ¿Seguro que no tiene desventajas cuando estoy produciendo un paquete de biblioteca de clases?
fuente
Hello World!
aplicación autónoma se reduce a <10 MB.Respuestas:
En el pasado, les dimos a los desarrolladores la recomendación de no hacer referencia al
NETStandard.Library
metapaquete ( ) de los paquetes NuGet, sino a los paquetes individuales, comoSystem.Runtime
ySystem.Collections
. La razón era que pensamos en el metapaquete como una abreviatura de un montón 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 admita algunos de estos bloques atómicos pero no todos. Por lo tanto, cuantos menos paquetes haga referencia, más portátil será. También hubo inquietudes con respecto a cómo nuestras herramientas tratan con gráficos de paquetes grandes.En el futuro, simplificaremos esto:
.NET Standard es un bloque de construcción atómico . En otras palabras, las nuevas plataformas no pueden crear subconjuntos de .NET Standard, tienen que implementarlo todo.
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 todavía se quemarán en la referencia a
NETStandard.Library
. No hay nada de malo en eso, simplemente se volverá redundante en el futuro.Actualizaré las preguntas frecuentes en el repositorio de .NET Standard para incluir esta pregunta.
Actualización : esta pregunta ahora forma parte de las preguntas frecuentes .
fuente
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 simplemente traigan NETStandard.Library en su lugar (en el caso de un proyecto de estilo SDK, esto se hará automáticamente por usted).
Nunca he obtenido una respuesta totalmente directa de por qué fue así, así que permítanme hacer algunas conjeturas.
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, se le solicitaría que realizara un seguimiento 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 ninguna referencia para obtener una parte decente de la plataforma (como solía hacer con las referencias predeterminadas en Desktop-land, especialmente mscorlib ).
Al introducir la metadefinición de lo que significa ser una
netstandard
biblioteca o unanetcoreapp
aplicación en el paquete NuGet apropiado, no tienen que incorporar ningún conocimiento especial en la definición de esas cosas como Visual Studio (odotnet new
) las 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 hacen compilación nativa para UWP (aunque con algunas advertencias). Hoy no hacen eso para .NET Core, pero supongo que es una optimización que han considerado (además de admitir código nativo).
No hay nada que le impida ser muy selectivo, si así lo desea. Creo que encontrará que es casi el único que lo hace, lo que también frustra el propósito (ya que se supondrá que todos están trayendo
NETStandard.Library
oMicrosoft.NETCore.App
).fuente
NETStandard.Library
. Es algo que se cumple, por supuesto ... si me dependeráNETStandard.Library
de Noda El tiempo, que los medios cualquier otra biblioteca construida en la cima de Noda El tiempo no tiene razón para dependencias de equipamiento, etc. Es tentador ser selectivo por ahora (Noda El tiempo es dirigiéndose hacia 2.0) y luego relájese un poco más tarde una vez que se hayan establecido las convenciones: cambiar de selectivo a basado en lib sería un cambio inquebrantable, supongo, pero lo contrario no es cierto.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
requeriría la dependencia.La biblioteca estándar de .NET es una especificación, un conjunto de ensamblados de referencia con los que se compila que proporciona un conjunto de API cuya existencia está garantizada 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 lo suficiente de la forma API para permitir que el compilador compile correctamente su código.
La implementación de estas API la proporciona 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
NETStandard.Library
paquete 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 de .NET Standard a la que se dirige proviene del marco de destino que especifica en su proyecto.
Si está creando una biblioteca y desea que se ejecute en .NET Standard 1.3, debe hacer referencia al
NETStandard.Library
paquete, actualmente en la versión 1.6.1. Pero lo que es más importante, el archivo de su proyecto debería apuntarnetstandard1.3
.El
NETStandard.Library
paquete le dará un conjunto diferente de ensamblados de referencia dependiendo de su apodo de marco de destino (estoy simplificando por brevedad, pero pienselib\netstandard1.0
,lib\netstandard1.1
y grupos de dependencia ). Entonces, si su proyecto tiene como objetivonetstandard1.3
, obtendrá los ensamblados de referencia 1.3. Si apuntanetstandard1.6
, obtendrá los ensamblados de referencia 1.6.Si está creando una aplicación, no puede apuntar a .NET Standard. No tiene sentido, no puede ejecutar una especificación. En su lugar, apuntas a plataformas concretas, como
net452
onetcoreapp1.1
. NuGet conoce la asignación entre estas plataformas y losnetstandard
monikers del marco de destino, por lo que sabe quélib\netstandardX.X
carpetas son compatibles con su plataforma de destino. También sabe que las dependencias deNETStandard.Library
las satisface la plataforma de destino, por lo que no incorporará ningún otro ensamblado.De manera similar, 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 incluye ninguna otra aplicación nueva.El único lugar que puedo imaginar donde podría ayudar eliminar la
NETStandard.Library
referencia es si está apuntando a una plataforma que no es compatible con .NET Standard, y puede encontrar un paquete de .NET Standard donde se pueden ejecutar todas las dependencias transitivas en su plataforma de destino. Sospecho que no hay muchos paquetes que se ajusten a ese presupuesto.fuente
dotnet publish
en un tiempo de ejecución específico, traerá todas las dependencias, incluido dotnet.exe (o su equivalente Linux / OS X). Esa debería ser una implementación completamente independiente en ese momento. Consulte los resultados de un proyecto de prueba unitaria: gist.github.com/bradwilson/6cc5a8fdfa18230aa6c99b851fb85c01