Предположим, у меня есть библиотека классов, которую я хочу нацелить на netstandard1.3, но также использую BigInteger
. Вот тривиальный пример - единственный исходный файл 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);
}
}
Вернувшись в мир project.json
, я бы нацелился netstandard1.3
на этот frameworks
раздел и имел явную зависимость System.Runtime.Numerics
, например, от версии 4.0.1. В создаваемом мной пакете nuget будет перечислена только эта зависимость.
В дивном новом мире csproj основе Dotnet инструментов (я использую v1.0.1 из инструментов командной строки) есть более подразумеваемая ссылка метапакета пакета для NETStandard.Library 1.6.1
при ориентации netstandard1.3
. Это означает, что мой файл проекта очень маленький, потому что ему не нужна явная зависимость:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
</PropertyGroup>
</Project>
... но созданный пакет nuget имеет зависимость NETStandard.Library
, что говорит о том, что для использования моей небольшой библиотеки вам понадобится все, что есть.
Оказывается, я могу отключить эту функцию с помощью DisableImplicitFrameworkReferences
, а затем снова добавить зависимость вручную:
<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>
Теперь мой пакет NuGet точно говорит, от чего он зависит. Интуитивно кажется, что это более компактный пакет.
Так в чем же разница для потребителя моей библиотеки? Если кто-то попытается использовать его в приложении UWP, означает ли вторая, «урезанная» форма зависимостей, что результирующее приложение будет меньше?
Не документируя DisableImplicitFrameworkReferences
четко (насколько я видел; я читал об этом в выпуске ) и делая неявную зависимость значением по умолчанию при создании проекта, Microsoft поощряет пользователей просто полагаться на метапакет - но как я могу быть уверены, что у меня нет недостатков, когда я создаю пакет библиотеки классов?
источник
Hello World!
автономного приложения уменьшен до <10 МБ.Ответы:
В прошлом мы рекомендовали разработчикам не ссылаться на метапакет (
NETStandard.Library
) из пакетов NuGet, а вместо этого ссылаться на отдельные пакеты, такие какSystem.Runtime
иSystem.Collections
. Обоснованием было то, что мы думали о метапакете как об сокращении для группы пакетов, которые фактически являлись атомарными строительными блоками платформы .NET. Предполагалось, что мы можем создать другую платформу .NET, которая поддерживает только некоторые из этих атомарных блоков, но не все из них. Следовательно, чем меньше пакетов вы ссылаетесь, тем более портативным вы будете. Были также опасения относительно того, как наши инструменты работают с большими графами пакетов.В дальнейшем мы упростим это:
.NET Standard - это атомарный строительный блок . Другими словами, новым платформам не разрешается подмножество .NET Standard - они должны реализовать все это.
Мы уходим от использования пакетов для описания наших платформ , включая .NET Standard.
Это означает, что вам больше не придется ссылаться на какие-либо пакеты NuGet для .NET Standard. Вы выразили свою зависимость с помощью папки lib, и именно так она работала для всех других платформ .NET, в частности .NET Framework.
Однако сейчас наш инструментарий по-прежнему будет гореть в ссылке на
NETStandard.Library
. В этом тоже нет вреда, просто в дальнейшем это станет лишним.Я обновлю FAQ в репозитории .NET Standard, чтобы включить этот вопрос.
Обновление : этот вопрос теперь является частью FAQ .
источник
Команда раньше рекомендовала выяснить, какой комплект был самый тонкий. Они больше этого не делают и рекомендуют вместо этого просто использовать NETStandard.Library (в случае проекта в стиле SDK это будет сделано автоматически за вас).
Я так и не получил однозначного ответа на вопрос, почему это так, поэтому позвольте мне сделать несколько обоснованных предположений.
Основная причина, вероятно, заключается в том, что это позволяет им скрыть различия в версиях зависимых библиотек, которые в противном случае вам пришлось бы отслеживать при смене целевых фреймворков. Это также гораздо более удобная система с файлами проекта на основе SDK, потому что вам, честно говоря, не нужны никакие ссылки, чтобы получить приличный кусок платформы (как вы привыкли со ссылками по умолчанию в Desktop-land, особенно mscorlib ).
Помещая мета-определение того, что значит быть
netstandard
библиотекой илиnetcoreapp
приложением в соответствующий пакет NuGet, им не нужно встраивать какие-либо специальные знания в определение этих вещей, какdotnet new
их видит Visual Studio (или ).Статический анализ можно использовать во время публикации, чтобы ограничить поставляемые библиотеки DLL, что они и делают сегодня при собственной компиляции для UWP (хотя и с некоторыми оговорками). Сегодня они не делают этого для .NET Core, но я предполагаю, что это оптимизация, которую они рассмотрели (а также поддержка собственного кода).
Ничто не мешает вам быть очень избирательным, если вы того пожелаете. Я полагаю, вы обнаружите, что это делаете вы почти единственный, что также противоречит цели (поскольку предполагается, что все вносят
NETStandard.Library
илиMicrosoft.NETCore.App
).источник
NETStandard.Library
. Это, конечно, в некоторой степени самореализующееся ... если я полагаюсь наNETStandard.Library
Noda Time, это означает, что у любой другой библиотеки, построенной на основе Noda Time, нет причин обрезать зависимости и т.д. идем к 2.0), а затем расслабьтесь немного позже, как только будут установлены соглашения - я полагаю, что переход от выборочного к основанному на библиотеке будет неразрывным изменением, но обратное неверно.Вам не нужно отключать неявную ссылку. Все платформы, на которых сможет работать библиотека, уже будут иметь сборки,
NETStandard.Library
которые потребуются зависимости.Стандартная библиотека .NET - это спецификация, набор эталонных сборок, с которыми вы компилируете, который предоставляет набор API, которые гарантированно существуют на известном наборе платформ и версиях платформ, таких как .NET Core или .NET Framework. . Это не реализация этих сборок, а только форма API, позволяющая компилятору успешно построить ваш код.
Реализация этих API обеспечивается целевой платформой, например .NET Core, Mono или .NET Framework. Они поставляются вместе с платформой, потому что являются неотъемлемой частью платформы. Таким образом, нет необходимости указывать меньший набор зависимостей - все уже есть, вы не будете это менять.
NETStandard.Library
Пакет предоставляет эти опорные узлы. Одна вещь, вызывающая замешательство, - это номер версии - это версия пакета 1.6.1, но это не означает «.NET Standard 1.6». Это просто версия пакета.Версия .NET Standard, на которую вы нацелены, исходит из целевой платформы, указанной в вашем проекте.
Если вы создаете библиотеку и хотите, чтобы она работала в .NET Standard 1.3, вы должны сослаться на
NETStandard.Library
пакет, который сейчас находится в версии 1.6.1. Но что более важно, ваш файл проекта будет нацелен наnetstandard1.3
.NETStandard.Library
Пакет даст вам другой набор эталонных сборок в зависимости от целевого рамочным прозвища (я упрощая для краткости, но думаетlib\netstandard1.0
,lib\netstandard1.1
и группы зависимостей ). Так что, если ваш проект нацеленnetstandard1.3
, вы получите эталонные сборки 1.3. Если вы нацелитесьnetstandard1.6
, вы получите эталонные сборки 1.6.Если вы создаете приложение, вы не можете настроить таргетинг на .NET Standard. В этом нет смысла - вы не можете работать по спецификации. Вместо этого вы ориентируетесь на конкретные платформы, такие как
net452
илиnetcoreapp1.1
. NuGet знает соответствие между этими платформами иnetstandard
именами целевой платформы, поэтому знает, какиеlib\netstandardX.X
папки совместимы с вашей целевой платформой. Он также знает, что зависимостиNETStandard.Library
удовлетворяются целевой платформой, поэтому не будет задействовать какие-либо другие сборки.Точно так же при создании автономного приложения .NET Core сборки реализации .NET Standard копируются вместе с вашим приложением. Ссылка на
NETStandard.Library
не вводит никаких других новых приложений.Единственное место, где я могу представить, где это может помочь удалить
NETStandard.Library
ссылку, - это если вы ориентируетесь на платформу, которая не поддерживает .NET Standard, и вы можете найти пакет из .NET Standard, в котором могут выполняться все транзитивные зависимости. на вашей целевой платформе. Я подозреваю, что не так много пакетов подошло бы под этот счет.источник
dotnet publish
для определенной среды выполнения, она внесет все зависимости, включая dotnet.exe (или его эквивалент для Linux / OS X). На тот момент это должно быть полностью автономное развертывание. Ознакомьтесь с результатами проекта модульного тестирования: gist.github.com/bradwilson/6cc5a8fdfa18230aa6c99b851fb85c01