Suponha que eu tenha uma biblioteca de classes que quero direcionar para netstandard1.3, mas também usar BigInteger
. Aqui está um exemplo trivial - o único arquivo de origem é 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 volta ao mundo de project.json
, eu teria como alvo netstandard1.3
noframeworks
seção e teria uma dependência explícita System.Runtime.Numerics
, por exemplo, da versão 4.0.1. O pacote nuget que crio listará apenas essa dependência.
No admirável mundo novo de ferramentas dotnet baseada csproj (estou usando v1.0.1 das ferramentas de linha de comando) há uma referência pacote metapackage implícita para NETStandard.Library 1.6.1
quando o direcionamento netstandard1.3
. Isso significa que meu arquivo de projeto é muito pequeno, porque não precisa da dependência explícita:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
</PropertyGroup>
</Project>
... mas o pacote nuget produzido tem uma dependência de NETStandard.Library
, o que sugere que, para usar minha pequena biblioteca, você precisa de tudo lá.
Acontece que posso desativar essa funcionalidade usando e DisableImplicitFrameworkReferences
, em seguida, adicionar a dependência manualmente novamente:
<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>
Agora meu pacote NuGet diz exatamente do que depende. Intuitivamente, parece um pacote "mais enxuto".
Então, qual é a diferença exata para um consumidor da minha biblioteca? Se alguém tentar usá-lo em um aplicativo UWP, a segunda forma "aparada" de dependências significa que o aplicativo resultante será menor?
Por não documentar DisableImplicitFrameworkReferences
claramente (pelo que vi; li sobre isso em uma edição ) e por tornar a dependência implícita o padrão ao criar um projeto, a Microsoft está encorajando os usuários a depender apenas do metapacote - mas como posso ser certeza de que não tem desvantagens quando estou produzindo um pacote de biblioteca de classes?
fonte
Hello World!
aplicativo independente é reduzido para <10 MB.Respostas:
No passado,
NETStandard.Library
fornecemos aos desenvolvedores a recomendação de não fazer referência ao meta pacote ( ) dos pacotes NuGet, mas sim fazer referência a pacotes individuais, comoSystem.Runtime
eSystem.Collections
. O raciocínio era que pensamos no meta pacote como uma abreviatura para um grupo de pacotes que eram os blocos de construção atômicos reais da plataforma .NET. A suposição era: podemos acabar criando outra plataforma .NET que suporte apenas alguns desses blocos atômicos, mas não todos eles. Conseqüentemente, quanto menos pacotes você referenciar, mais portátil você será. Também havia preocupações sobre como nosso ferramental lida com gráficos de pacotes grandes.Seguindo em frente, vamos simplificar isso:
.NET Standard é um bloco de construção atômico . Em outras palavras, novas plataformas não têm permissão para criar subconjuntos do .NET Standard - elas precisam implementar tudo isso.
Estamos deixando de usar pacotes para descrever nossas plataformas , incluindo .NET Standard.
Isso significa que você não precisará mais fazer referência a nenhum pacote NuGet para .NET Standard. Você expressou sua dependência com a pasta lib, que é exatamente como funcionou para todas as outras plataformas .NET, em particular .NET Framework.
No entanto, neste momento, nosso ferramental ainda queima na referência a
NETStandard.Library
. Não há mal nenhum nisso, apenas se tornará redundante no futuro.Atualizarei as perguntas frequentes sobre o repositório .NET Standard para incluir esta pergunta.
Atualização : Esta questão agora faz parte do FAQ .
fonte
A equipe recomendava descobrir qual era o conjunto de pacotes mais fino. Eles não fazem mais isso e recomendam que as pessoas simplesmente tragam NETStandard.Library (no caso de um projeto no estilo SDK, isso será feito automaticamente para você).
Eu nunca obtive uma resposta totalmente direta sobre o porquê disso, então deixe-me fazer alguns palpites.
O motivo principal provavelmente é que isso permite que eles ocultem as diferenças nas versões das bibliotecas dependentes que, de outra forma, você teria que rastrear ao mudar as estruturas de destino. É também um sistema muito mais amigável com os arquivos de projeto baseados em SDK, porque você francamente não precisa de nenhuma referência para obter uma parte decente da plataforma (como costumava fazer com as referências padrão no Desktop-land, especialmente mscorlib )
Empurrando a meta-definição do que significa ser uma
netstandard
biblioteca ou umnetcoreapp
aplicativo para o pacote NuGet apropriado, eles não precisam incluir nenhum conhecimento especial na definição dessas coisas como o Visual Studio (oudotnet new
) os vê.A análise estática pode ser usada durante a publicação para limitar as DLLs enviadas, algo que eles fazem hoje ao fazer a compilação nativa para UWP (embora com algumas ressalvas). Eles não fazem isso hoje para o .NET Core, mas presumo que seja uma otimização que eles consideraram (além de oferecer suporte a código nativo).
Não há nada que o impeça de ser muito seletivo, se assim escolher. Acredito que você descobrirá que é quase o único a fazer isso, o que também anula o propósito (uma vez que se presume que todos estão trazendo
NETStandard.Library
ouMicrosoft.NETCore.App
).fonte
NETStandard.Library
. É um tanto auto-realizável, é claro ... se eu depender doNETStandard.Library
Tempo Noda, isso significa que qualquer outra biblioteca construída em cima do Tempo Noda não tem razão para cortar dependências, etc. É tentador ser seletivo agora (o Tempo Noda é em direção a 2.0) e relaxe um pouco mais tarde, uma vez que as convenções tenham sido estabelecidas - mudar de seletivo para baseado em lib seria uma mudança ininterrupta, eu suponho, mas o inverso não é verdade.Você não deve precisar desativar a referência implícita. Todas as plataformas nas quais a biblioteca poderá ser executada já terão os assemblies que a
NETStandard.Library
dependência exigiria.A Biblioteca .NET Standard é uma especificação, um conjunto de assemblies de referência que você compila e que fornece um conjunto de APIs cuja existência é garantida em um conjunto conhecido de plataformas e versões de plataformas, como .NET Core ou .NET Framework . Não é uma implementação desses assemblies, apenas o suficiente da forma da API para permitir que o compilador construa seu código com êxito.
A implementação dessas APIs é fornecida por uma plataforma de destino, como .NET Core, Mono ou .NET Framework. Eles são enviados com a plataforma, porque são uma parte essencial da plataforma. Portanto, não há necessidade de especificar um conjunto de dependências menor - tudo já está lá, você não vai mudar isso.
O
NETStandard.Library
pacote fornece esses assemblies de referência. Um ponto de confusão é o número da versão - o pacote é a versão 1.6.1, mas isso não significa ".NET Standard 1.6". É apenas a versão do pacote.A versão do .NET Standard que você está almejando vem da estrutura de destino especificada em seu projeto.
Se você estiver criando uma biblioteca e quiser que ela seja executada no .NET Standard 1.3, consulte o
NETStandard.Library
pacote, atualmente na versão 1.6.1. Mas o mais importante, seu arquivo de projeto seria direcionadonetstandard1.3
.O
NETStandard.Library
pacote fornecerá um conjunto diferente de assemblies de referência, dependendo de seu moniker de estrutura de destino (estou simplificando para ser breve, mas penselib\netstandard1.0
,lib\netstandard1.1
e grupos de dependência ). Portanto, se o seu projeto for direcionadonetstandard1.3
, você obterá os assemblies de referência 1.3. Se você mirarnetstandard1.6
, obterá os assemblies de referência 1.6.Se você estiver criando um aplicativo, não poderá direcionar o .NET Standard. Não faz sentido - você não pode executar em uma especificação. Em vez disso, você visa plataformas de concreto, como
net452
ounetcoreapp1.1
. O NuGet conhece o mapeamento entre essas plataformas e osnetstandard
identificadores de estrutura de destino, portanto, sabe quaislib\netstandardX.X
pastas são compatíveis com sua plataforma de destino. Ele também sabe que as dependências deNETStandard.Library
são satisfeitas pela plataforma de destino, portanto, não puxará nenhum outro assembly.Da mesma forma, ao criar um aplicativo .NET Core autônomo, os assemblies de implementação do .NET Standard são copiados com seu aplicativo. A referência a
NETStandard.Library
não traz nenhum outro aplicativo novo.O único lugar que posso imaginar onde pode ajudar a remover a
NETStandard.Library
referência é se você está almejando uma plataforma que não oferece suporte ao .NET Standard e você pode encontrar um pacote do .NET Standard onde todas as dependências transitivas podem ser executadas em sua plataforma de destino. Suspeito que não existam muitos pacotes que se encaixem nesse perfil.fonte
dotnet publish
em um tempo de execução específico, ele trará todas as dependências, incluindo dotnet.exe (ou seu equivalente Linux / OS X). Essa deve ser uma implantação totalmente autônoma nesse ponto. Confira os resultados de um projeto de teste de unidade: gist.github.com/bradwilson/6cc5a8fdfa18230aa6c99b851fb85c01