standard net framework entre diferencias c# .net uwp .net-core portable-class-library

c# - framework - diferencias entre.net y.net core



¿Diferencia entre.Net Core, Portable, Standard, Compact, UWP y PCL? (3)

He oído hablar de

  • .Net Core
  • .Net Portable
  • Estándar .Net
  • .Net Compact
  • Plataforma universal de Windows
  • Bibliotecas portátiles de clase

Todos estos me fueron explicados como "un subconjunto de la .Net completa que te permite apuntar a múltiples plataformas" . Así que mis preguntas son

  1. ¿¡Cual es la diferencia!?
  2. Si quiero escribir una biblioteca que sea utilizable para una audiencia lo más amplia posible, ¿ cuál (o más de estas) debo usar?

(Mi situación específica: tengo una biblioteca que se enfoca en .Net 2.0, .Net 4.5 y UWP. El objetivo de UWP requirió crear un nuevo proyecto de VS y vincular todos los archivos existentes, lo cual es un gran dolor. Ahora alguien me dice que no lo hace). ¿No funciona para PCL, y por su sonido tengo que volver a hacerlo para .Net Standard?


Como se vincula en los comentarios, here que resume toda esta información. Sin embargo, según su respuesta, parece que no entendió completamente todo el asunto. Es muy largo, así que aquí está (con suerte) una versión tl; dr.

Comenzaremos con la siguiente tabla del enlace anterior, y esperamos que esto aclare algo de la confusión:

Un breve resumen para otras personas que lo encuentran más adelante: las bibliotecas .NET han pasado por muchos cambios y puertos durante sus 15 años de existencia. En ese momento, muchos teléfonos inteligentes son ahora tan potentes como algunos escritorios que se usaron en 2001. En ese intervalo, se crearon (y se abandonaron rápidamente) subconjuntos del marco .NET para su uso en diferentes plataformas. Con el nuevo enfoque de Satya Nadella para hacer de .NET el mayor alcance posible de una plataforma, las cosas deben cambiar.

Al ser una tecnología de 15 años, las cosas necesitaban ser mejoradas. .NET Core se ha trabajado desde 2014 como una revisión completa de la arquitectura .NET. Se ha reescrito desde cero como una nueva versión del lenguaje .NET. Uno de los objetivos de Core era habilitar la implementación multiplataforma. Ya sea que se trate de una aplicación que se ejecute en un iPhone / Android / XBox One, o un sitio web que pueda hospedarse en IIS, o en una caja de Linux, .NET Core lo tiene cubierto. Lo hace de varias maneras diferentes, incluyendo no requerir que .NET Framework esté instalado en la máquina, y en su lugar empaquetará las bibliotecas necesarias con su solución.

Más notablemente con .NET Core son los cambios drásticos en ASP.NET. El viejo System.Web se ha ido completamente y se ha reescrito para que tenga el mejor rendimiento posible con resultados impresionantes . Los controladores WebApi independientes se han ido, ya que todo se hace dentro de un solo controlador. Ahora todo el proceso es opt-in, en lugar de tener un valor predeterminado para permitir cosas que tal vez no desee.

Sin embargo, como desarrolladores querremos migrar algunas aplicaciones eventualmente, entonces, ¿cómo podemos estar seguros de que el código que ya hemos escrito no ha tenido algunos pequeños cambios menores en los métodos para romper la compilación de soluciones gigantes? En viene el estándar .NET . Este es un conjunto de API que deben implementarse para que su plataforma se llame a sí misma ".NET".

Como el .NET Framework básico con el que hemos estado trabajando durante años está bien establecido, se usó como base para lo que abarcará el estándar. Sin embargo, todo no está incluido, ¿cuál sería el punto? Entonces, el Estándar es solo lo que las API comunes existirán entre los distintos tipos de plataformas .NET. Eventualmente no escribirá el código en ".NET Standard".

Microsoft compró Xamarin (incluido en la tabla anterior) y esa tecnología se utilizó para ayudar a construir (o al menos inspirar) .NET Core para que sea multiplataforma. Todavía existe como herramienta, pero en las mismas venas que se usó en el pasado. Según la tabla, será compatible con .NET Standard 2.0 en la versión vNext. Sin embargo, su público objetivo no cambiará.

Para responder directamente a su pregunta, si desea escribir una aplicación con la solución de implementación única más amplia posible, desearía usar .NET Core . Sin embargo, si está utilizando una biblioteca que actualmente se basa en .NET Framework 2.0 y 4.5, entonces se quedará atascado utilizando .NET Framework y tendrá esa solución UWP separada para ese objetivo.

Si proporciona algo a lo que puede llamar a través de una llamada de la API web, podría tenerlo ejecutándose en su servidor en .NET Framework y tener una solución única en .NET Core para implementarla en sus usuarios finales. Si está integrado a su código, desafortunadamente no tendrá suerte hasta que se proporcione una actualización de .NET Core.

Esperemos que esto haya aclarado parte de la confusión entre los diferentes nombres de tecnología.

EDITAR

Después de algunas aclaraciones sobre su situación específica, puedo aclarar las cosas para usted. No se puede hacer una solución única que se dirija tanto a .NET Framework como a .NET Core. La compilación es completamente diferente, con diferentes tecnologías subyacentes, por lo que esta es la misma situación en la que se intenta utilizar su versión .NET 4.5 en una solución .NET 2.0.

Sin embargo, hay tutorials para permitirle portar su proyecto a Core. En su mayor parte, simplemente copie los cuerpos de clase en su solución .NET Core, y la mayoría de las cosas funcionarán correctamente. Hay algunas piezas que se han abandonado, otras que aún no se han desarrollado completamente al 100% (no para su caso, pero Entity Framework no tiene todas las mismas características, por ejemplo). También hay algunas llamadas que han cambiado un poco.

La buena noticia es que, mientras avanzamos, .NET Core le brindará el alcance más amplio posible. .NET Framework no va a desaparecer, pero Core y estarán mucho más sincronizados entre sí.

El otro beneficio de .NET Core es que utiliza un enfoque iterativo para la implementación, por lo que no esperará 2 años para la próxima actualización importante. Con todo lo que se entrega a través de NuGet, tendrá un giro mucho más rápido en mejoras y nuevas características.


Contestaré tu segunda pregunta primero:

Tengo una biblioteca que se dirige a .Net 2.0, .Net 4.5 y UWP. El objetivo de UWP requería crear un nuevo proyecto VS y vincular todos los archivos existentes, lo que es un gran dolor. Ahora alguien me está diciendo que no funciona para PCL, y por su sonido, ¡¿tengo que volver a hacerlo para .Net Standard ?!

Si quiero escribir una biblioteca que sea utilizable para una audiencia lo más amplia posible, ¿cuál (o más de estas) debo usar?

Respuesta corta: debes apuntar a netstandard . Use la versión más baja que tenga todas las API que necesita. Puede usar una herramienta como el puerto API para verificar la compatibilidad de su proyecto existente con una versión de netstandard determinada .

Desafortunadamente, este enfoque dejará atrás las plataformas más antiguas, en su caso, .NET 2.0. Si es necesario mantener la compatibilidad con .NET 2.0, entonces necesitará un proyecto separado (con archivos vinculados) para construir un ensamblado .NET 2.0 separado.

A los detalles ...

¿¡Cual es la diferencia!?

  • .Net Standard ( netstandard ): esta es la nueva API BCL multiplataforma. Es un "estándar" en el sentido de que es solo una definición de API y no una implementación. La idea es que puede compilar su biblioteca para (una versión de) esta API y se ejecutará en cualquier plataforma que admita esa versión.
  • .Net Core : puede pensar en esto como una implementación de referencia de netstandard (con algunos bits adicionales). Es una implementación multiplataforma de esa API. Es posible que las interfaces de usuario y otros marcos puedan basarse en él, pero por ahora su único punto de apoyo está actuando como la plataforma de elección para ASP.NET Core. [Nota: por razones históricas, ".NET Core" es completamente diferente al objetivo de netcore netcore; cuando estás en un contexto NuGet, netcore significa "Windows 8 / 8.1 / 10"] .
  • Las bibliotecas de clases portátiles y portátiles de .Net : las bibliotecas de clases portátiles (PCL) son un enfoque de denominador menos común para proporcionar una API multiplataforma. Cubren una amplia gama de plataformas de destino , pero están incompletas y no están preparadas para el futuro. En esencia, han sido reemplazados por netstandard .
  • .Net Compact : este es un marco .NET completamente diferente con su propia API única. Es completamente incompatible con cualquier otro framework, PCL o versión netstandard ; como tal, es mucho más difícil de soportar que cualquier otra plataforma. Sin embargo, todavía se utiliza en dispositivos con restricciones de memoria ajustadas.
  • Plataforma universal de Windows : se trata de una fusión de la era Win10 de la API entre Windows Phone y el escritorio, lo que permite escribir aplicaciones / bibliotecas de la Tienda Windows para ambas plataformas. Esto ha sido esencialmente reemplazado por netstandard .

Supongo que ya has leído el artículo de Microsoft con la bonita tabla y ahora todo está claro como un barro. Si es así, estás en el mismo bote que tenía antes de pasar la mayor parte de la tarde investigando esto (y tratando de trasladar mi gran biblioteca de reflexiones a .NET Core, que debería mencionar también es mi única .NET Esfuerzo portante del núcleo). Lo que sigue no es la línea oficial del partido, sino mi resumen personal de lo que encontré a través de mucha lectura (y de ser un desarrollador de .NET desde .NET 1.0). No puedo responder por su total precisión (especialmente cuando se trata del desarrollo móvil, del cual soy casi totalmente ignorante) y las correcciones son bienvenidas. Si hay un montón lo haré wiki.

Lo recorreré más o menos cronológicamente porque descubrí que tiene más sentido si quiere comprender cómo se relacionan lo antiguo y lo nuevo. Probablemente debería reducirse mucho, pero en este momento no tengo tiempo para hacerlo. Sin embargo, hay una versión de TL; DR al final.

El largo y ventoso camino

A pesar de su ascendencia Java, .NET nunca ha intentado seriamente "escribir una vez, ejecutar en cualquier lugar". Comenzó en gran medida en el campo de Windows, y aunque se compila a bytecode y no fue exagerado con el Windowsism explícito y, por lo tanto, es teóricamente muy portátil, no era eso lo que realmente le interesaba a MS. Parte del .NET Framework era De código abierto desde el principio, y un grupo de entusiastas de código abierto lo recogieron y corrieron con él, lo que nos dio Mono . Mono es importante porque es la primera plataforma alternativa y conjunto de bibliotecas para .NET e ilustra las ideas de plataforma frente a biblioteca frente a toolchain. Mono intenta dar una implementación más o menos completa del Common Language Runtime y su biblioteca de clases base asociada. Esto es importante: aunque Mono se ejecuta en Linux (y en algunos otros Unices) no es un formulario separado porque implementa (algunas versiones de) el CLR + BCL. Existen diferencias en el tiempo de ejecución (nombres de ruta y similares) que son importantes para los desarrolladores de aplicaciones, pero para la programación práctica de bibliotecas, puede considerar que Mono y .NET Framework para Windows son "la misma plataforma" con una implementación ligeramente diferente. Hago hincapié en esto porque vamos a encontrar un código .NET dirigido a Windows que no se está ejecutando en el CLR y que es (más irónicamente o no) más difícil de portar.

Luego aparecieron Windows Phone (varias versiones), Windows CE (varias versiones), Windows Embedded CE, Windows Toaster (OK, esa no existe realmente) y básicamente se reinventaba un poco de .NET cada vez, aún así .NET pero con cosas fundamentales del tiempo de ejecución y / o BCL que faltan o cambian. Aquí es donde obtenemos .NET Compact , .NET Micro , Windows Phone (estilo antiguo, sin nombre separado para el marco) y Silverlight . Todos estos deben considerarse combinaciones de plataforma + biblioteca separadas que se parecen a .NET Framework lo suficiente como para hacer posible el desarrollo multiplataforma, pero se diferencian de él lo suficiente como para que no sea tan fácil . Al realizar un seguimiento de lo que se admitía donde era más incómodo para las bibliotecas compartidas, a alguien se le ocurrió la idea de las bibliotecas de clases portátiles y sus perfiles asociados (cuya colección se conoce como .NET Portable Reference Assemblies ).

Básicamente, se dirige a un conjunto de combinaciones específicas de versión .NET, plataforma (y biblioteca), y obtiene conjuntos de referencia que imitan esas combinaciones para compilar. Existen muchos perfiles diferentes en función de los sabores que desea orientar explícitamente. Este fue un primer intento de lo que .NET Standard está probando ahora en una escala mayor. Básicamente, PCL ahora está obsoleto a menos que esté apuntando a algo .NET Standard no está tratando de admitirlo . .NET Standard elimina la idea de un bazillón de perfiles diferentes, lo cual es bueno, a costa de cortar algunas cosas que su biblioteca podría apuntar antes, lo cual es malo. Hay recursos en línea para ayudar con la transición de PCL a .NET Standard. Si está viendo un código portátil ahora , no desea centrarse en PCL a menos que realmente quiera apoyar algunas plataformas bastante marginales (sin ofender a las personas que aún están desarrollando para ellos).

Universal Windows Platform es, como su nombre lo indica, una plataforma. Específicamente, es la plataforma .NET que es compatible con las aplicaciones de la Tienda Windows (tanto en el escritorio como en el teléfono). Eso es, ni más, ni menos. Es mejor considerado como el sucesor natural de Silverlight, ya que se trata de un soporte de marco de arena para escritorio y móvil. A pesar del nombre, no es una plataforma universal y no es lo que quiere que apunte todo su código. Es una plataforma que tal vez desee habilitar para su código, y es única ya que es la única plataforma que conozco que tiene dos tiempos de ejecución en la misma versión. ¡Ya viene!

.NET Native no se mencionó en la publicación original, pero a menudo aparece en estas discusiones porque también es nuevo, como .NET Core, y suena muy atractivo porque compila .NET directamente en el código de la máquina (compilación anticipada, no Compilación JIT). No es una nueva plataforma completa, sino un nuevo tiempo de ejecución para las aplicaciones UWP (y solo esas) cuando se compila en el modo Release. En el modo de depuración, usan el CoreCLR (el tiempo de ejecución de .NET Core). No tendrás que pensar mucho en esto a menos que realmente desees construir una aplicación UWP, porque hay todo tipo de cosas interesantes que se desarrollan con la reflexión en .NET Native que necesita atención por separado del desarrollador de la aplicación.

Y ahora llegamos a .NET Core ! .NET Core comenzó como "ASP.NET Core", pero la gente se dio cuenta rápidamente de que podría ser mucho más grande que eso. .NET Core es un nuevo combo de biblioteca en tiempo de ejecución (CoreCLR) + con soporte explícito multiplataforma (como en cross-OS). A diferencia del combo CLR + BCL, donde hay una versión de Windows y una versión de Unix en forma de Mono, .NET Core es una base de código para todas las plataformas (con los bits crujientes específicos de la plataforma habitual para admitir la capa portátil mullida de arriba, por supuesto) . Lo que más confunde a la gente es que .NET Core también es el nombre de un nuevo tipo de proyecto / cadena de herramientas para apoyar la creación de aplicaciones .NET Core, donde antes solo teníamos MSBuild. Esto fue necesario porque no existía Visual Studio para Linux, pero MS ya se está alejando de este enfoque de "seamos sencillo y JSON" y regresa a un formato universal para .NET Framework y .NET Core (y va a Sé MSBuild, porque hay mucho más en eso.

.NET Core es en su mayor parte muy compatible con .NET Framework. Como resultado, si su aplicación .NET Core se está ejecutando realmente en .NET Framework (en Windows), puede cargar ensamblajes dirigidos a .NET Framework, no simplemente .NET Core. Esta es una fuente importante de confusión y código no transportable: aunque puede compilar y cargar esos ensamblajes, harán que su código no sea portátil. .NET Core en sí mismo no te impedirá hacer esto; .NET Standard (próximamente) lo hará, si alinea sus declaraciones correctamente.

Conmigo hasta ahora? Bien, porque ahora estamos listos para colocar .NET Standard en su cabeza desprevenida. .NET Standard no es una plataforma (en el sentido de que no puede descargarla e instalarla en una máquina), no es una biblioteca (pero hay paquetes para admitirla con fines de compilación), es un perfil. Es un intento de estandarizar la superficie de la biblioteca en una amplia gama de las cosas que acabamos de discutir. La idea es que, si su código apunta a .NET Standard XY, solo necesita cambiar sus herramientas de compilación a "dame .NET Standard XY" y cuando compile su ensamblaje, puede estar seguro de que será utilizable para todas las plataformas cubierto por XY Hooray! ¡El mundo es simple otra vez!

Bueno, todavía no lo es. El problema es que .NET Core está en un gran desarrollo en este momento, lo que significa que faltan muchas cosas o son diferentes, incluso cosas bastante fundamentales que pueden estar presentes de forma natural en el código base de .NET Framework, como marcar las excepciones como Serializable y otorgarlas. un constructor separado para la deserialización, por lo que funcionan bien en AppDomain s. No hay AppDomain s en .NET Core, por lo tanto, no hay serialización, por lo tanto, esos constructores no compilarán. Incluso el propio atributo Serializable falta en las versiones anteriores de CoreCLR. Si su proyecto de MSBuild usa objetivos personalizados, muy mal, el .NET Core toolchain no tiene soporte para esas cosas en este momento (puede que, en el futuro, cuando sea MSBuild nuevamente). Puede volver a escribir, por supuesto, pero no reutilizar. Entonces, si bien puede apuntar a .NET Standard, es posible que necesite dos proyectos separados y / o alguna compilación condicional para obtener su ensamblaje .NET Standard para dos plataformas diferentes. Si tiene suerte (o puede comprometerse un poco), su biblioteca es lo suficientemente simple como para construirla solo con .NET Core. Sin embargo, no se equivoque: todavía hay varias plataformas .NET y todavía tienen sus diferencias. El estándar .NET simplemente trata de facilitar el puerto. Hasta ahora es limitado, pero ya está haciendo un trabajo más limpio que PCL.

Para resumir un poco: .NET Core y .NET Framework (y todos sus primos y sobrinos) son plataformas separadas, tanto conceptualmente como por implementación. .NET Standard es un perfil de segmentación que simplifica los esfuerzos necesarios para transferir el código entre ellos (pero aún no lo hace completamente transparente). PCL es el precursor de la norma que se puede ignorar si eres progresivo.

TL; DR comienza aquí (pero sigue siendo TL)

Para responder finalmente a su pregunta, ¿qué debe hacer si es un desarrollador de bibliotecas moderno y desea dirigirse a "la mayor audiencia posible"? Bueno, primero que todo, debes hacer esto más pequeño si es posible. ¿Con qué plataformas apoyará y probará explícitamente ? ¿Realmente quieres apuntar a .NET Compact en tu XBox 360? Windows Phone 7? ¿El Silverlight de hace ocho años? Si lo haces, probablemente no puedas evitar el PCL, pero la mayoría de nosotros tendrá el lujo de evitarlo. Si no es así: ponga en cola una compilación PCL separada si su perfil no coincide con nada en el estándar .NET.

¿Es su biblioteca muy simple (sin reflejo, sin async / await , sin dependencias en marcos más grandes como WCF)? Entonces, podrá orientar la sección transversal de .NET 2.0 y la versión más baja de .NET Standard que tiene las dependencias de marco que necesita. No se deje engañar, las versiones inferiores de .NET Standard están realmente decepcionantemente limitadas en lo que ofrecen, pero usted tiene que pagar algún precio por la portabilidad. No hay soporte de herramientas para compilar tanto para .NET 2.0 como para algunas versiones estándar de .NET. Debe compilarlo dos veces y probarlo "en todas partes", aunque la sección transversal significa que puede estar razonablemente seguro de que funcionará si se compila. La biblioteca resultante admitirá todas y cada una de las plataformas .NET que pueden cargar ensamblajes vanilla .NET 2.0 (que son casi todos ellos, pero en particular no Micro y Compact) y .NET Core, y todos sin conmutadores de plataforma. Felicidades, el mundo nunca ha visto algo tan portátil!

¿Usará la biblioteca la reflexión? Entonces, probablemente no pueda reescribir el código para compilarlo para .NET Core, porque la API de reflexión cambió hace un tiempo y es posible que su código no se haya puesto al día todavía (ya que no era necesario que siguiera apuntando al marco completo) solamente). En este caso, querrá pasar su versión de .NET Framework a 4.5, ya que esta es la versión de .NET Framework que es compatible con estos cambios. Aquí comienza a obtener soporte de herramientas: puede orientarse a .NET Standard 1.1, que cubre un subconjunto de .NET 4.5. Si encuentra que este subconjunto no es suficiente, nuevamente tendrá que recurrir a compilar dos veces: para .NET Framework completo y para .NET Core. La razón es que .NET Core 1.0 admite "más" que .NET Framework 4.5, pero aún no hay una versión de .NET Framework a la que pueda apuntar que esté a la par con Core (que será "vNext"). Por lo tanto, si no desea restringirse solo a .NET Core, sino que también quiere que sea compatible con aquellos de nosotros que todavía estamos creando aplicaciones de escritorio 4.5 tradicionales .NET Standard 1.1 no es suficiente para usted, tendrá que dividirse. Lo que está mal hacer es apuntar 1.1 y luego importar paquetes / ensamblados solo de Framework 4.5, ¡ya que esto te llevará a lo peor de ambos mundos en términos de portabilidad!

¿Necesitará su biblioteca algunas de las mejoras / extensiones sobre 4.5 que se introdujeron en 4.5.1 o posterior, o paquetes que solo están disponibles para versiones superiores de .NET Standard? Luego dirígete a la versión estándar. Tenga en cuenta que Microsoft ya no admite oficialmente ninguna versión 4.x inferior a 4.5.2 . Esto no significa que no debas apuntar a esas versiones (ir tan bajo como puedas razonablemente), pero significa que tienes un argumento para usar nada menos que .NET Standard 1.2, y si puedes exigir 4.6, no menos que 1.5. Esto no es una carga para los consumidores (si está dispuesto y es capaz de instalar 4.6, es casi seguro que desea y puede instalar 4.6.2) y le facilita la vida. Dependiendo de su código, puede salirse con la única construcción de .NET Core, pero es probable que no quiera hacerlo, porque la cadena de construcción de .NET Core aún no es estable y volverá a MSBuild (como se mencionó anteriormente). ¡No tiene ningún sentido deshacerse de todos los archivos de su proyecto para JSON solo para volver atrás más tarde!

¿Utiliza tu biblioteca algún tipo de compilación condicional? Ten cuidado, con la cadena de herramientas .NET Core, obtienes diferentes símbolos predefinidos . Son extremadamente súper molestos porque insisten en (por ejemplo) hacer una distinción entre 4.5, 4.5.1 y 4.5.2, lo cual es una molestia si se quiere cubrir "4.5 y más allá". Nada que una compilación cuidadosa no pueda manejar, pero, sin embargo, algo que hay que tener en cuenta.

No estoy cubriendo las versiones móviles aquí (Xamarin y versiones anteriores de Phone) porque, bueno, ¡sé muy poco acerca de ellas! Me imagino que la historia es muy similar a compilar tanto para .NET Core como para .NET Framework, en ese edificio una vez solo funciona para bibliotecas simples y bibliotecas donde no tiene que preocuparse por la compatibilidad con versiones anteriores, y las necesidades (al menos) dos compilaciones de lo contrario, pero como dije al principio, las correcciones son bienvenidas.