Diferença entre o núcleo de .net, portátil, padrão, compacto, UWP e PCL?

Eu já ouvi falar

  • .Net Core
  • .Net Portable
  • Padrão .Net
  • .Net Compact
  • Plataforma Universal do Windows
  • Bibliotecas de Classes Portáteis

Todos estes foram explicados para mim como “um subconjunto do .Net completo que permite que você segmente múltiplas plataformas” . Então minhas perguntas são

  1. Qual é a diferença!?
  2. Se eu quiser escrever uma biblioteca que seja utilizável para o maior público possível, qual (ou mais de uma) delas eu preciso usar?

(Minha situação específica: Eu tenho uma biblioteca que alveja .Net 2.0, .Net 4.5 e UWP. Alvejando UWP necessária a criação de um novo projeto VS e ligando todos os arquivos existentes, o que é uma grande dor.Agora alguém está me dizendo que doesn não trabalho para PCL, e pelo som dele eu tenho que fazer isso novamente para .Net Standard !?)

Eu responderei sua segunda pergunta primeiro:

Eu tenho uma biblioteca que alveja .Net 2.0, .Net 4.5 e UWP. A segmentação por UWP exigia a criação de um novo projeto VS e a vinculação de todos os arquivos existentes, o que é uma grande dor. Agora alguém está me dizendo que não funciona para PCL, e pelo som de que eu tenho que fazer isso novamente para .net padrão !?)

Se eu quiser escrever uma biblioteca que seja utilizável para o maior público possível, qual (ou mais de uma) delas eu preciso usar?

Resposta curta: você deve segmentar netstandard . Use a versão mais baixa com todas as APIs de que você precisa. Você pode usar uma ferramenta como o API Port para verificar seu projeto existente quanto à compatibilidade com uma determinada versão do netstandard .

Infelizmente, esta abordagem deixará plataformas mais antigas, no seu caso, o .NET 2.0. Se for necessário manter o suporte ao .NET 2.0, você precisará de um projeto separado (com arquivos vinculados) para criar um assembly .NET 2.0 separado.

Para os detalhes …

Qual é a diferença!?

  • .Net Standard ( netstandard ) – esta é a nova API BCL multiplataforma. É um “padrão” no sentido de que é apenas uma definição de API e não uma implementação. A ideia é que você possa compilar sua biblioteca para (uma versão desta) API e ela será executada em qualquer plataforma que suporte essa versão.
  • .Net Core – você pode pensar nisso como uma implementação de referência do netstandard (com alguns bits extras). É uma implementação de plataforma cruzada dessa API. É possível que as interfaces de usuário e outras estruturas possam se basear nela, mas, por enquanto, sua única base segura é a plataforma de escolha do ASP.NET Core. [Nota: por razões históricas, “.NET Core” é completamente diferente do alvo netcore NuGet; quando você está em um contexto NuGet, netcore significa “Windows 8 / 8.1 / 10”] .
  • Bibliotecas de classs portáteis e portáteis do .net – as bibliotecas de class portáteis (PCLs) são uma abordagem de mínimo denominador comum para fornecer uma API de plataforma cruzada. Cobrem uma ampla gama de plataformas de destino , mas estão incompletas e não são preparadas para o futuro. Eles foram essencialmente substituídos pelo netstandard .
  • .Net Compact – Este é um framework .NET completamente diferente, com sua própria API exclusiva. É completamente incompatível com qualquer outra estrutura, PCL ou versão netstandard ; como tal, é muito mais difícil de suportar do que qualquer outra plataforma. No entanto, ainda é usado em dispositivos com restrições de memory apertadas.
  • Plataforma Universal do Windows – Essa era uma fusão da API entre o Windows Phone e a área de trabalho da era Win10, permitindo que aplicativos / bibliotecas da Windows Store fossem gravados para ambas as plataformas. Isso foi essencialmente substituído pelo netstandard .

Como ligado nos comentários, já existe uma descrição pela Microsoft que descreve todas essas informações. No entanto, pela sua resposta, parece que você não entendeu completamente a coisa toda. É muito longo, então aqui está (espero) uma versão completa.

Começaremos com a seguinte tabela do link acima, e esperamos que isso elimine um pouco da confusão:

Conformidade com o padrão .NET

Uma breve visão geral de outras pessoas que descobrirão isso depois: As bibliotecas .NET passaram por muitas mudanças e portas ao longo de seus 15 anos de existência. Naquela época, muitos smartphones agora são quase tão poderosos quanto alguns desktops que estavam em uso em 2001. Nesse interminável, subconjuntos do .NET foram criados (e rapidamente abandonados) para uso em diferentes plataformas. Com a nova abordagem de Satya Nadella para tornar o .NET tão abrangente quanto possível de uma plataforma, as coisas precisavam mudar.

Sendo uma tecnologia de 15 anos, as coisas precisavam ser melhoradas. O .NET Core tem sido trabalhado desde 2014 como uma revisão completa da arquitetura .NET. Foi reescrito do zero como uma nova versão da linguagem .NET. Um dos objectives do Core era permitir a implantação entre plataformas. Seja um aplicativo para ser executado em um iPhone / Android / XBox One ou um site que pode ser hospedado no IIS ou em uma checkbox do Linux, o .NET Core cuida de você. Ele faz isso de várias maneiras, incluindo não exigir que o .NET Framework seja instalado na máquina e, em vez disso, empacota as bibliotecas necessárias com a sua solução.

Mais notavelmente com o .NET Core são as mudanças drásticas no ASP.NET. O antigo System.Web desapareceu completamente e foi reescrito para ser o mais eficiente possível com resultados impressionantes . Os controladores WebApi separados desapareceram, já que tudo é feito dentro de um único controlador. Todo o processo é agora opt-in, em oposição à falta de permissão para permitir coisas que você pode não querer.

No entanto, nós, desenvolvedores, desejaremos migrar algumas aplicações eventualmente, então como podemos ter certeza de que o código que já escrevemos não teve várias pequenas alterações de nome nos methods, quebrando assim a compilation de soluções gigantes? Em vem o padrão de .NET . Este é um conjunto de APIs que devem ser implementadas para que sua plataforma se chame “.NET”.

Como o .NET Framework básico com o qual estamos trabalhando há anos é bem estabelecido, ele foi usado como base para o que o Padrão englobará. No entanto, tudo não está incluído, como o que seria o ponto? Portanto, o padrão é apenas o que as APIs comuns existirão entre os vários tipos de plataformas .NET. Você não irá eventualmente escrever código em “.NET Standard”.

Xamarin (incluído na tabela acima) foi comprado pela Microsoft em 2016, e essa tecnologia foi usada para ajudar a construir (ou pelo menos inspirar) o .NET Core para ser multi-plataforma. Ela ainda existe como uma ferramenta, mas nas mesmas veias que foi usada no passado. De acordo com a tabela, ela será compatível com o .NET Standard 2.0 na versão vNext. No entanto, o público-alvo não será alterado.

Para responder diretamente à sua pergunta, se você quiser escrever um aplicativo com a solução de implantação única mais ampla possível, convém usar o .NET Core . No entanto, se você estiver usando uma biblioteca que atualmente é construída sobre o .NET Framework 2.0 e 4.5, você estará preso usando o .NET Framework e tendo essa solução UWP separada para esse destino.

Se ele fornecer algo que você possa chamar por meio de uma chamada de API da Web, você poderá executá-lo em seu servidor no .NET Framework e terá uma única solução no .NET Core para implantar em seus usuários finais. Se estiver integrado ao seu código, infelizmente você estará sem sorte até que uma atualização do .NET Core seja fornecida.

Espero que isso tenha esclarecido parte da confusão entre os diferentes nomes de tecnologia.

EDITAR

Depois de algum esclarecimento sobre sua situação específica, posso esclarecer as coisas para você. Você não pode criar uma única solução que tenha como alvo o .NET Framework e o .NET Core. A compilation é feita de maneiras completamente diferentes, com diferentes tecnologias subjacentes, portanto, é a mesma situação que tentar usar sua versão .NET 4.5 em uma solução .NET 2.0.

No entanto, há tutoriais por aí para permitir que você transfira seu projeto para o Core. Na maior parte, apenas copie os corpos de classs para sua solução .NET Core, e a maioria das coisas funcionará corretamente. Há algumas peças que foram abandonadas, algumas ainda não foram completamente completadas (não para o seu caso, mas o Entity Framework não tem todos os mesmos resources, por exemplo). Há também algumas chamadas que mudaram um pouco.

O bom é que, no futuro, o .NET Core lhe dará o maior alcance possível. O .NET Framework não está indo embora, mas ele e o Core estarão muito mais sincronizados entre si.

O outro benefício para o .NET Core é que ele usa uma abordagem iterativa para implantação, de modo que você não estará esperando dois anos para a próxima grande atualização. Com tudo sendo entregue por meio do NuGet, você terá uma reviravolta muito mais rápida em melhorias e novos resources.

Estou assumindo que você já leu o artigo da Microsoft com a boa mesa e tudo está claro como lama agora. Se assim for, você está no mesmo barco que eu era antes de passar a maior parte de uma tarde olhando para isso (e tentando portar minha biblioteca de reflection pesada para o .NET Core, que eu deveria mencionar também é meu único .NET. Esforço de portagem principal). O que se segue não é a linha oficial do partido, mas meu resumo pessoal do que eu encontrei através de muita leitura (e de ser um desenvolvedor .NET desde o .NET 1.0). Eu não posso garantir sua precisão total (especialmente quando se trata de desenvolvimento móvel, do qual eu sou quase totalmente ignorante) e correções são certamente bem vindas. Se houver muitos, eu apenas farei wiki.

Vou percorrê-lo mais ou menos cronologicamente, porque descobri que isso faz mais sentido se você quiser entender como o velho e o novo se relacionam. Provavelmente deveria ser muito reduzido, mas no momento não tenho tempo para fazê-lo. Existe uma versão TL; DR no final, no entanto.

A longa e sinuosa estrada

Apesar de sua ascendência Java, o .NET nunca tentou seriamente “gravar uma vez, executar em qualquer lugar”. Começou como muito no campo do Windows, e apesar de compilar para bytecode e não exagerar com o Windowsisms explícito e é, portanto, teoricamente muito portátil, não é isso que a MS estava realmente interessada. Parte do .NET Framework foi fonte aberta desde o início, e um monte de enthousiasts open source pegou e correu com ele, dando-nos Mono . O Mono é importante porque é a primeira plataforma alternativa e conjunto de bibliotecas para .NET e ilustra as ideias de plataforma versus biblioteca versus toolchain. O Mono tenta fornecer uma implementação (mais ou menos) completa do Common Language Runtime e está associada à Base Class Library. Isso é importante: embora o Mono seja executado no Linux (e em alguns outros Unices), ele não é uma plataforma separada, pois implementa (algumas versões) o CLR + BCL. Existem diferenças de tempo de execução (nomes de caminho e similares) que importam para os desenvolvedores de aplicativos, mas para a programação prática de bibliotecas, é possível considerar o Mono e o .NET Framework para Windows “a mesma” plataforma com uma implementação um pouco diferente. Eu enfatizo isso porque vamos encontrar o código .NET que alveja o Windows que não está rodando no CLR e que (ironicamente ou de outra forma) é mais difícil de portar.

Então veio o Windows Phone (múltiplas versões), Windows CE (múltiplas versões), Windows Embedded CE, Windows Toaster (OK, esse não existe realmente) e algum sabor do .NET foi basicamente reinventado toda vez – ainda .NET mas com material fundamental do tempo de execução e / ou BCL ausente ou alterado. É aqui que obtemos o .NET Compact , o .NET Micro , o Windows Phone (estilo antigo, sem nome separado para a estrutura) e o Silverlight . Todos esses devem ser considerados combos separados de plataforma + biblioteca que se assemelhem ao .NET Framework o suficiente para tornar possível o desenvolvimento de plataforma cruzada, mas diferem dele o suficiente para tornar isso não tão fácil . Como manter o controle do que foi suportado, onde se tornou mais inconveniente para bibliotecas compartilhadas, alguém surgiu com a ideia de Portable Class Libraries e seus perfis associados (cuja coleção é conhecida como o .NET Portable Reference Assemblies ).

Basicamente, você tem como alvo um conjunto de combinações específicas de versão .NET, plataforma (e biblioteca), e você obteria assemblies de referência que imitavam essas combinações para compilar. Existem muitos perfis diferentes dependendo de quais sabores você deseja segmentar explicitamente. Esta foi uma primeira tentativa do que o .NET Standard agora está tentando em uma escala maior. Basicamente, o PCL agora está obsoleto, a menos que você esteja direcionando algo que o .NET Standard não está tentando suportar . O .NET Standard acaba com a ideia de perfis diferentes, o que é bom, em detrimento do corte de algumas coisas que sua biblioteca poderia ter como alvo anteriormente, o que é ruim. Existem resources online para ajudar na transição do PCL para o .NET Standard. Se você está olhando para código portátil agora , você não quer se concentrar em PCL, a menos que você realmente queira oferecer suporte a algumas plataformas bastante marginais (sem ofensas destinadas a pessoas que ainda estão desenvolvendo para elas).

Plataforma Universal do Windows é, como o nome indica, uma plataforma. Especificamente, é a plataforma .NET suportada pelos aplicativos da Windows Store (na área de trabalho e no telefone). É isso, nem mais nem menos. É melhor considerado como o sucessor natural do Silverlight, pois é um suporte de estrutura em área restrita para computadores e dispositivos móveis. Apesar do nome, não é uma plataforma universal e não é o que você deseja que seu código segmente. É uma plataforma que você pode querer ativar para o seu código, e é única porque é a única plataforma que eu conheço que tem dois tempos de execução na mesma versão. Chegando bem!

O .NET Native não foi mencionado no post original, mas frequentemente aparece nessas discussões porque também é novo, como o .NET Core, e soa muito sexy porque compila o .NET diretamente ao código de máquina (compilation antecipada, não Compilação JIT). Não é uma nova plataforma completa, mas um novo tempo de execução para aplicativos UWP (e somente aqueles) quando compilados no modo Release. No modo de debugging, eles usam o CoreCLR (o tempo de execução do .NET Core). Você não precisará pensar muito sobre isso, a menos que realmente queira construir um aplicativo UWP, porque há todo tipo de coisa interessante acontecendo com o .NET nativo que precisa de atenção separada do desenvolvedor do aplicativo.

E agora chegamos ao .NET Core ! O .NET Core começou como “ASP.NET Core”, mas as pessoas perceberam rapidamente que poderia ser muito maior do que isso. O .NET Core é um novo combo de tempo de execução (CoreCLR) + biblioteca com suporte explícito de plataforma cruzada (como em cross-OS). Ao contrário do combo CLR + BCL, onde há uma versão do Windows e uma versão Unix na forma de Mono, o .NET Core é uma base de código para todas as plataformas (com os bits crocantes específicos da plataforma para suportar a camada portátil acima, é claro) . O que mais confunde as pessoas é que o .NET Core também é o nome de um novo tipo de conjunto de ferramentas / projeto para dar suporte à criação de aplicativos .NET Core, onde antes nós só tínhamos o MSBuild. Isso foi necessário por não haver o Visual Studio para Linux, mas a MS já está se afastando dessa abordagem “vamos mantê-la simples e JSON” e voltando para um formato universal para o .NET Framework e o .NET Core (e seja MSBuild, porque há muito mais a descansar sobre isso).

O .NET Core é, na maior parte, muito compatível com o .NET Framework. Como resultado, se o seu aplicativo .NET Core estiver sendo executado no .NET Framework (no Windows), ele poderá carregar assemblies que tenham como alvo o .NET Framework, não apenas o .NET Core. Essa é uma fonte importante de confusão e código não suportável: embora você possa construir e carregar esses assemblies, eles tornarão seu código não portátil. O próprio .NET Core não vai impedi-lo de fazer isso; O padrão .NET (que vem logo acima) será, se você alinhar suas declarações corretamente.

Comigo até agora? Bom, porque agora estamos prontos para descartar o .NET Standard em sua cabeça desavisada. O .NET Standard não é uma plataforma (no sentido de que você não pode baixá-lo e instalá-lo em uma máquina), ele não é uma biblioteca (mas existem pacotes para suportá-lo para propósitos de construção), é um perfil. É uma tentativa de padronizar a superfície da biblioteca em uma ampla gama de coisas que acabamos de discutir. A ideia é que, se o seu código tiver como alvo o .NET Standard XY, você só precisa mudar suas ferramentas de construção para “me fornecer .NET padrão XY” e, ao criar seu assembly, você pode ter certeza de que ele será utilizável em todas as plataformas coberto por XY Hooray! O mundo é simples de novo!

Bem, ainda não é. O problema é que o .NET Core está em grande desenvolvimento no momento, significando que muitas coisas estão faltando ou são diferentes – mesmo coisas bastante fundamentais que podem estar naturalmente presentes em sua base de código .NET Framework, como marcar suas exceções Serializable e dar a elas um construtor separado para desserialização, para que funcionem bem em AppDomain s. Não há AppDomain s no .NET Core, portanto, nenhuma serialização, portanto, esses construtores não serão compilados. Até mesmo o atributo Serializable está faltando nas versões mais antigas do CoreCLR. Se o seu projeto MSBuild usa destinos personalizados, muito ruim, o conjunto de ferramentas do .NET Core não tem suporte para essas coisas no momento (pode, no futuro, quando for novamente o MSBuild). Você pode rewrite, é claro, mas não reutilizar. Portanto, embora você possa segmentar o .NET Standard, talvez seja necessário dois projetos separados e / ou alguma compilation condicional para obter seu assembly .NET Standard para duas plataformas diferentes. Se você tiver sorte (ou puder comprometer um pouco), sua biblioteca é simples o suficiente para que a construção com o .NET Core seja suficiente. Não se engane, porém: ainda existem várias plataformas .NET e elas ainda têm suas diferenças, o .NET Standard apenas tenta tornar mais fácil a portabilidade. Até agora, é limitado, mas já está fazendo um trabalho mais limpo que o PCL.

Resumindo: o .NET Core e o .NET Framework (e todos os seus priminhos e sobrinhos) são plataformas separadas conceitualmente e por implementação. O .NET Standard é um perfil de segmentação que simplifica os esforços necessários para o código de porta entre eles (mas ainda não o torna completamente transparente). PCL é o precursor do padrão que pode ser desconsiderado se você for progressivo.


TL; DR começa aqui (mas ainda é TL)

Para finalmente responder à sua pergunta, o que você deve fazer se for um desenvolvedor moderno de bibliotecas e quiser segmentar “o maior público possível”? Bem, primeiro de tudo, você deve fazer isso menor, se possível. Quais plataformas você explicitamente suportará e testará? Você realmente quer direcionar o .NET Compact no seu XBox 360? Windows Phone 7? O Silverlight de oito anos atrás? Se o fizer, você provavelmente não poderá contornar o PCL, mas a maioria de nós terá o luxo de poder evitar isso. Caso contrário: crie uma fila de PCL separada se o seu perfil não corresponder a nada no .NET Standard.

Sua biblioteca é muito simples (usando sem reflection, sem async / await , sem dependencies em frameworks maiores como o WCF)? Em seguida, você poderá segmentar a seção cruzada do .NET 2.0 e a versão mais baixa do .NET Standard que possui as dependencies de estrutura necessárias. Não se deixe enganar, as versões inferiores do .NET Standard são realmente decepcionantemente limitadas no que oferecem, mas você tem que pagar algum preço pela portabilidade. Não há suporte a toolchain para criar tanto o .NET 2.0 quanto algumas versões do .NET Standard. Você deve construí-lo duas vezes e testá-lo “em todos os lugares”, embora a seção transversal signifique que você pode estar razoavelmente seguro de que funcionará se ele compilar. A biblioteca resultante suportará todas as plataformas .NET que podem carregar conjuntos .NET 2.0 (que são quase todos eles, mas notavelmente não Micro e Compact) e .NET Core, e todos sem alternância de plataforma. Parabéns, o mundo nunca viu algo tão portátil!

Sua biblioteca usará reflection? Então você provavelmente não conseguirá rewrite o código para compilá-lo para o .NET Core, porque a API de reflection mudou um tempo atrás e seu código pode não ter sido detectado ainda (já que não havia necessidade se você continuasse direcionando o framework completo só). Você desejará aumentar sua versão do .NET Framework para este 4.5, pois esta é a versão do .NET Framework que é compatível com essas mudanças. Aqui você começa a obter suporte a ferramentas: você pode segmentar o .NET Standard 1.1, que abrange um subconjunto do .NET 4.5. Se você achar que este subconjunto não é suficiente, você terá que recorrer novamente à construção duas vezes: para o .NET Framework completo e para o .NET Core. A razão é que o .NET Core 1.0 suporta “mais” que o .NET Framework 4.5, mas ainda não existe uma versão do .NET Framework que você possa atingir que seja equivalente ao Core (que será “vNext”). Então, se você não quer se restringir ao .NET Core apenas, mas também quer apoiar aqueles de nós que estão construindo apenas 4.5 aplicativos de desktop e o .NET Standard 1.1 não é o suficiente para você, você terá que dividir. A coisa errada a fazer é segmentar 1.1 e, em seguida, importar somente pacotes / montagens do Framework 4.5, pois isso fará com que você tenha o pior dos dois mundos em termos de portabilidade!

Sua biblioteca precisará de alguns dos aprimoramentos / extensões acima de 4.5 que foram introduzidos no 4.5.1 ou posterior, ou pacotes que estão disponíveis apenas para versões superiores do .NET Standard? Em seguida, segmente a versão superior do .NET Standard apropriada. Observe que a Microsoft não suporta oficialmente qualquer 4.x menor que 4.5.2 . Isso não significa que você não deve direcionar essas versões (vá tão baixo quanto puder razoavelmente), mas isso significa que você tem um argumento para usar nada menos que o .NET Standard 1.2, e se você pode exigir 4.6, não menos que 1.5. Isso não é oneroso para os consumidores (se você estiver disposto a instalar o 4.6, é quase certo que você está disposto a instalar o 4.6.2) e facilitar a sua vida. Dependendo do seu código, você pode obter apenas uma compilation .NET Core, mas provavelmente não deseja, porque a cadeia de compilation do .NET Core ainda não está estável e voltará para o MSBuild (como mencionado anteriormente). Não faz sentido abandonar todos os seus arquivos de projeto para JSON e voltar novamente mais tarde!

Sua biblioteca usa algum tipo de compilation condicional? Cuidado, com o toolchain .NET Core, você obtém diferentes símbolos predefinidos . Eles são extremamente super irritantes porque insistem em (digamos) fazer uma distinção entre 4.5, 4.5.1 e 4.5.2, o que é uma dor se você quiser cobrir “4.5 e além”. Nada que uma construção cuidadosa não possa suportar, mas mesmo assim algo que você precisa levar em conta.

Eu não estou cobrindo versões móveis aqui (Xamarin e versões mais antigas do telefone) porque, bem, eu sei muito pouco sobre isso! Eu imagino que a história é muito parecida com a construção do .NET Core e do .NET Framework, em que o edifício funciona apenas para bibliotecas e bibliotecas simples nas quais você não precisa se preocupar com a compatibilidade retroativa e precisa (pelo menos) dois constrói de outra forma, mas como eu disse no começo, correções são bem-vindas.