Supposons que je dispose d'une bibliothèque de classes que je souhaite cibler netstandard1.3, mais que j'utilise également BigInteger
. Voici un exemple trivial - le seul fichier source est 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 retour dans le monde de project.json
, je ciblerais netstandard1.3
dans la frameworks
section, et aurais une dépendance explicite sur System.Runtime.Numerics
, par exemple la version 4.0.1. Le package nuget que je crée ne listera que cette dépendance.
Dans le nouveau monde de l' outillage de base dotnet csproj (J'utilise v1.0.1 des outils de ligne de commande) , il y a une référence paquet métapaquet implicite à NETStandard.Library 1.6.1
lors du ciblage netstandard1.3
. Cela signifie que mon fichier projet est vraiment petit, car il n'a pas besoin de la dépendance explicite:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
</PropertyGroup>
</Project>
... mais le paquet nuget produit a une dépendance sur NETStandard.Library
, ce qui suggère que pour utiliser ma petite bibliothèque, vous avez besoin de tout .
Il s'avère que je peux désactiver cette fonctionnalité en utilisant DisableImplicitFrameworkReferences
, puis ajouter à nouveau la dépendance manuellement:
<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>
Maintenant, mon package NuGet dit exactement de quoi il dépend. Intuitivement, cela ressemble à un paquet "allégé".
Alors, quelle est la différence exacte pour un consommateur de ma bibliothèque? Si quelqu'un essaie de l'utiliser dans une application UWP, est-ce que la deuxième forme de dépendances "rognée" signifie que l'application résultante sera plus petite?
En ne documentant pas DisableImplicitFrameworkReferences
clairement (pour autant que je l'ai vu; je l'ai lu dans un numéro ) et en faisant de la dépendance implicite la dépendance par défaut lors de la création d'un projet, Microsoft encourage les utilisateurs à dépendre simplement du métapaquet - mais comment puis-je être sûr que cela n'a pas d'inconvénients lorsque je produis un package de bibliothèque de classes?
la source
Hello World!
application autonome est réduite à <10 Mo.Réponses:
Dans le passé, nous avons recommandé aux développeurs de ne pas référencer le meta package (
NETStandard.Library
) des packages NuGet, mais plutôt de référencer des packages individuels, commeSystem.Runtime
etSystem.Collections
. Le raisonnement était que nous considérions le méta-package comme un raccourci pour un ensemble de packages qui étaient les véritables blocs de construction atomiques de la plate-forme .NET. L'hypothèse était la suivante: nous pourrions finir par créer une autre plate-forme .NET qui ne prend en charge que certains de ces blocs atomiques, mais pas tous. Par conséquent, moins vous référencez de packages, plus vous serez portable. Il y avait également des préoccupations concernant la façon dont nos outils traitent les grands graphiques de paquets.À l'avenir, nous simplifierons ceci:
.NET Standard est un bloc de construction atomique . En d'autres termes, les nouvelles plates-formes ne sont pas autorisées à sous-ensembles .NET Standard - elles doivent tout mettre en œuvre.
Nous abandonnons l'utilisation de packages pour décrire nos plates - formes , y compris .NET Standard.
Cela signifie que vous n'aurez plus à référencer aucun package NuGet pour .NET Standard. Vous avez exprimé votre dépendance avec le dossier lib, qui est exactement la façon dont il a fonctionné pour toutes les autres plates-formes .NET, en particulier .NET Framework.
Cependant, pour le moment, notre outillage brûlera toujours dans la référence à
NETStandard.Library
. Il n'y a pas de mal à cela non plus, cela deviendra tout simplement redondant à l'avenir.Je mettrai à jour la FAQ sur le référentiel .NET Standard pour inclure cette question.
Mise à jour : Cette question fait désormais partie de la FAQ .
la source
L'équipe avait l'habitude de recommander de déterminer quel était le paquet le plus mince. Ils ne le font plus et recommandent aux gens de simplement apporter NETStandard.Library à la place (dans le cas d'un projet de type SDK, cela se fera automatiquement pour vous).
Je n'ai jamais obtenu de réponse totalement simple quant à la raison de cette situation, alors permettez-moi de faire des suppositions éclairées.
La raison principale est probablement que cela leur permet de masquer les différences dans les versions des bibliothèques dépendantes que vous seriez autrement obligé de suivre vous-même lors du changement de framework cible. C'est également un système beaucoup plus convivial avec les fichiers de projet basés sur le SDK, car vous n'avez franchement pas besoin de références pour obtenir une bonne partie de la plate-forme (tout comme vous le faisiez avec les références par défaut dans Desktop-land, en particulier mscorlib ).
En poussant la méta-définition de ce que signifie être une
netstandard
bibliothèque ou unenetcoreapp
application dans le package NuGet approprié, ils n'ont pas à intégrer de connaissances spéciales dans la définition de ces éléments tels que Visual Studio (oudotnet new
) les voit.L'analyse statique pourrait être utilisée lors de la publication pour limiter les DLL livrées, ce qu'ils font aujourd'hui lors de la compilation native pour UWP (avec quelques mises en garde). Ils ne le font pas aujourd'hui pour .NET Core, mais je suppose que c'est une optimisation qu'ils ont envisagée (en plus de prendre en charge le code natif).
Rien ne vous empêche d'être très sélectif, si vous le souhaitez. Je crois que vous constaterez que vous êtes presque le seul à le faire, ce qui va également à l'encontre du but (car on supposera que tout le monde apporte
NETStandard.Library
ouMicrosoft.NETCore.App
).la source
NETStandard.Library
. C'est un peu auto-réalisateur, bien sûr ... si je dépendsNETStandard.Library
de Noda Time, cela signifie que toute autre bibliothèque construite sur Noda Time n'a aucune raison de réduire les dépendances, etc. Il est tentant d'être sélectif pour le moment (Noda Time est se dirigeant vers 2.0) puis relâchez un peu plus tard une fois que les conventions ont été établies - passer de sélectif à lib-based serait un changement sans rupture, je suppose, mais l'inverse n'est pas vrai.Vous ne devriez pas avoir besoin de désactiver la référence implicite. Toutes les plates-formes sur lesquelles la bibliothèque pourra s'exécuter auront déjà les assemblys
NETStandard.Library
requis par la dépendance.La bibliothèque standard .NET est une spécification, un ensemble d'assemblys de référence sur lesquels vous compilez et qui fournit un ensemble d'API dont l'existence est garantie sur un ensemble connu de plates-formes et de versions de plates-formes, telles que .NET Core ou .NET Framework . Ce n'est pas une implémentation de ces assemblys, juste assez de la forme de l'API pour permettre au compilateur de générer avec succès votre code.
L'implémentation de ces API est fournie par une plate-forme cible, telle que .NET Core, Mono ou .NET Framework. Ils sont livrés avec la plate-forme, car ils sont une partie essentielle de la plate-forme. Il n'est donc pas nécessaire de spécifier un ensemble de dépendances plus petit - tout est déjà là, vous ne changerez pas cela.
Le
NETStandard.Library
package fournit ces assemblys de référence. Un point de confusion est le numéro de version - le package est la version 1.6.1, mais cela ne signifie pas ".NET Standard 1.6". C'est juste la version du package.La version du .NET Standard que vous ciblez provient du framework cible que vous spécifiez dans votre projet.
Si vous créez une bibliothèque et que vous souhaitez qu'elle s'exécute sur .NET Standard 1.3, vous référeriez le
NETStandard.Library
package, actuellement à la version 1.6.1. Mais plus important encore, votre fichier projet cibleraitnetstandard1.3
.Le
NETStandard.Library
package vous donnera un ensemble différent d'assemblys de référence en fonction de votre surnom de framework cible (je simplifie par souci de brièveté, mais pensezlib\netstandard1.0
,lib\netstandard1.1
et des groupes de dépendances ). Donc, si votre projet ciblenetstandard1.3
, vous obtiendrez les assemblys de référence 1.3. Si vous cibleznetstandard1.6
, vous obtiendrez les assemblys de référence 1.6.Si vous créez une application, vous ne pouvez pas cibler le standard .NET. Cela n'a pas de sens - vous ne pouvez pas exécuter sur une spécification. Au lieu de cela, vous ciblez des plates-formes concrètes, telles que
net452
ounetcoreapp1.1
. NuGet connaît le mappage entre ces plates-formes et lesnetstandard
monikers du framework cible, donc sait quelslib\netstandardX.X
dossiers sont compatibles avec votre plate-forme cible. Il sait également que les dépendances deNETStandard.Library
sont satisfaites par la plate-forme cible, donc ne tirera aucun autre assemblage.De même, lors de la création d'une application .NET Core autonome, les assemblys d'implémentation .NET Standard sont copiés avec votre application. La référence à
NETStandard.Library
n'apporte aucune autre nouvelle application.Le seul endroit où je peux imaginer où il pourrait être utile de supprimer la
NETStandard.Library
référence est si vous ciblez une plate-forme qui ne prend pas en charge le .NET Standard, et vous pouvez trouver un package du .NET Standard où toutes les dépendances transitives peuvent s'exécuter sur votre plateforme cible. Je soupçonne qu'il n'y a pas beaucoup de forfaits qui conviendraient à cette facture.la source
dotnet publish
un runtime spécifique, il introduira toutes les dépendances, y compris dotnet.exe (ou son équivalent Linux / OS X). Cela devrait être un déploiement complètement autonome à ce stade. Consultez les résultats d'un projet de test unitaire: gist.github.com/bradwilson/6cc5a8fdfa18230aa6c99b851fb85c01