¿Por qué my.NET ¿El paquete NuGet estándar activa tantas dependencias?


He estado jugando con un proyecto estándar.NET y NuGet. Tengo un proyecto en funcionamiento y lo he subido a NuGet.org . Mi proyecto se dirige a.NET Standard 1.3, que debería soportar. NET Framework 4.6 y. NET Core 1.0.

Pero cuando intenté agregar mi proyecto (a través de NuGet) a un nuevo proyecto de. NET Framework 4.6, las dependencias resolvieron 47 ¡paquetes! Son todas bibliotecas del sistema y parecen ser dependencias de cualquiera Microsoft.NETCore.Plataformas o NETStandard.Biblioteca 1.6.1. (Esencia de la salida de PM completa.)

Mi proyecto solo importa (using) un puñado de bibliotecas, ninguna de las cuales agregué manualmente; es decir, todas son bibliotecas que "vienen con". NET Standard. Estas bibliotecas son:

  1. Sistema
  2. Sistema.Texto
  3. Sistema.Reflexión
  4. Sistema.Linq
  5. Sistema.Colecciones.Genérico;

La cosa es que decidí hacer mi objetivo de proyecto. NET Estándar porque quería que funcionara sin problemas en las aplicaciones. NET Framework y. NET Core. Pensé que el objetivo del Estándar era establecer un nivel mínimo de compatibilidad. Por extensión, supongo que había asumido (quizás erróneamente) que a las bibliotecas les gusta System.La consola estaría disponible automáticamente en Core o Framework.

No noté nada como esto cuando probé mi proyecto estándar como una dependencia en un proyecto Framework y Core dentro de la misma solución, así que estoy sospechoso de que esto podría ser una cosa NuGet.

¿Qué está pasando realmente aquí? ¿Y cómo puedo hacer que mi biblioteca Estándar. NET esté disponible en NuGet sin una gran lista de dependencias?

¿Es un problema con la forma en que he especificado mi paquete NuGet? ¿O he entendido mal algo fundamentalmente?

Author: Tom Wright, 2017-11-18

2 answers

No has hecho nada malo, se espera que esto suceda. Si no desea nada más que agregar su propia DLL a un nuevo proyecto de. NET Framework, debe apuntar a. NET Standard 2.0 para su biblioteca espere una versión de. NET Framework que admita de forma nativa tanto la API como las versiones de ensamblado, que será 4.7.2 (mientras que. NET Framework 4.7.1 admite todas las API, hubo errores con la forma en que se versionan algunos ensamblados y, por lo tanto, las herramientas (VS 2017 15.5+) agregarán ensamblajes para arreglar eso).

Lo que está viendo son los efectos secundarios de cómo se construye.NET Standard y se implementa el soporte para los frameworks soportados. Esto también es diferente según la versión estándar de. NET a la que se dirige y las herramientas utilizadas para hacer referencia al paquete de la biblioteca.

En.NET Standard NETStandard.Library que a su vez hace referencia a paquetes adicionales (System.*). Esos paquetes contienen los ensamblados de referencia que componen el estándar". NET Contract " - un conjunto de API y los nombres de ensamblado + versiones.

Cuando una aplicación hace referencia al paquete NuGet que crea para.NET Standard 1.0-1.6, estos paquetes individuales no traen los ensamblados de referencia, sino más bien ensamblados de implementación para el marco al que se dirige la aplicación.

Para.NET Core, estos coinciden con los ensamblados que ya forman parte del tiempo de ejecución, por lo que los archivos DLL no terminarán junto a la aplicación construida. Sin embargo, esto cambió cuando se lanzó un nuevo conjunto de paquetes para. NET Core 1.1 (NETStandard.Library versión 1.6.1). Esto dio lugar a que las aplicaciones creadas para.NET Core 1.0 terminaran recibiendo ensamblados de implementación más nuevos que estaban destinados a ser incluidos en. NET Core 1.1 (afortunadamente, 1.1 se convirtió en la versión de "soporte a largo plazo", ya que provocó una discusión sobre qué ensamblados son parte de la promesa de LTS).

En. NET Framework estas bibliotecas (con algunas excepciones como System.Net.Http) no hacen mucho , solo reenvían a los ensamblajes del sistema. Así, por ejemplo, el "contrato" define que System.Object se define en un ensamblado System.Runtime.dll. Por lo tanto, el archivo System.Runtime.dll con el que termina en una aplicación de.NET Framework contiene un System.Runtime.dll que contiene el tipo reenviar a mscorlib.dll de. NET Framework. . NET Core ya contiene un System.Runtime.dll diferente que hace algo diferente para esa plataforma. Este mecanismo permite que un único archivo DLL funcione en ambas plataformas ya que esos reenvíos de tipo e implementaciones adicionales aseguran el mismo "contrato" (tipos + ensamblajes + versiones ensambladas) trabajando en ambas implementaciones.

. NET Standard 2.0 tenía como objetivo reducir el número de paquetes y DLLs que son necesarios y también eliminar las actualizaciones que requieren NETStandard.Library cada vez que se lanza una nueva versión de. NET Core.

Así que para.NET Standard 2.0 y. NET Core 2.0, el paquete NETStandard.Library solo trae ensamblados de referencia para compilar código a un proyecto, pero el paquete NuGet resultante ya no depende de este paquete. Así que cuando creas una segmentación de biblioteca . NET Standard 2.0 y publíquelo, no tendrá dependencias NuGet (a menos que agregue otras adicionales).

La lógica de lo que las "bibliotecas de soporte" deben traer cuando se consume una biblioteca estándar.NET se trasladó a las herramientas que se utilizan durante la compilación. Por lo tanto, cuando se agrega una biblioteca que contiene una referencia a netstandard.dll a un proyecto de.NET Framework, las herramientas agregarán las DLL de soporte necesarias basadas en la versión de. NET Framework que se esté utilizando. Esto se hizo para. NET Estándar 2.0, así como . NET Standard 1.5 + desde. NET Framework 4.6.1 se hizo compatible retroactivamente con. NET Standard 2.0 (anteriormente era 1.4) a través de este tipo de archivos DLL. La misma herramienta también se asegura de que incluso si los paquetes de NuGet se introducen de alguna manera en un proyecto de aplicación de este tipo, cualquier biblioteca de implementación estándar de.NET introducida a través de NuGet se elimine de la compilación. Por lo tanto, si hace referencia a un paquete NuGet. NET Standard 1.0 que se construyó cuando se lanzó. NET Core 1.0, todas sus dependencias NuGet son recortado y obtiene las bibliotecas de soporte enviadas con las herramientas de compilación en su lugar.

La idea era que. NET Framework 4.7.1 contendría todos los ensamblados necesarios "bandeja de entrada" para que un netstandard.dll, System.Runtime.dll etc. son parte de. NET Framework y cualquier archivo DLL. NET Standard 1.0-2.0 "simplemente funcionaría", el problema era que estos archivos dll "bandeja de entrada" tenían un número de versión demasiado bajo para algunos ensamblados, por lo que las bibliotecas no podían cargarse - esto se solucionó cambiando las herramientas nuevamente para incluir archivos DLL con números de versión más altos como bibliotecas de soporte que a su vez reenvían a los ensamblados de.NET Framework "inbox". Está previsto que esto se solucione en. NET Framework 4.7.2.

 34
Author: Martin Ullrich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-20 22:04:42

Acabo de encontrarme con este problema también. La entrada del blog que enlazaste en un comentario a la respuesta de Martin Ullrich me llevó a una solución que funcionó para mí: Usar NuGet multi-targeting . Cambiando:

<TargetFramework>netstandard1.0</TargetFramework>

A

<TargetFrameworks>netstandard1.0;netstandard2.0;net45</TargetFrameworks>

En el archivo project .csproj. Esto hace que el proyecto se construya por separado para cada framework de destino y el paquete NuGet resultante solo depende de NETStandard.Library para netstandard1.0. Desde NuGet elige los binarios net45 para cualquier. NET Framework completo version , esto evita las dependencias innecesarias al instalar el paquete.

 0
Author: Kevinoid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-06 19:34:04