Подтвердить что ты не робот

Как упаковать переносимую библиотеку .NET, ориентированную на .NET Core?

Как я могу упаковать переносимую библиотеку .NET в современном общем виде? Предположим, что у меня есть одна сборка AnyCPU, которую я хочу сделать доступной для любой платформы .NET, которая поддерживает поверхность .NET Core API, например .NET Framework 4.6 и Universal Windows Platform.

Это серия вопросов и ответов, которые документируют мои выводы по теме современного дизайна пакетов NuGet, особенно с учетом изменений, внесенных в NuGet 3. Вам также могут быть интересны некоторые связанные вопросы:

4b9b3361

Ответ 1

Этот ответ основывается на принципах используемых для упаковки библиотек, ориентированных на .NET Framework. Сначала прочитайте связанный ответ, чтобы лучше понять следующее.

Чтобы опубликовать переносимую библиотеку .NET, вам необходимо создать пакет NuGet со следующей структурой:

\---lib
    \---dotnet
            MyPortableLibrary.dll
            MyPortableLibrary.pdb
            MyPortableLibrary.XML

Все три файла поступают из вашего выходного каталога сборки проекта в конфигурации сборки выпуска.

Каталог dotnet в вышеприведенной структуре имеет особое значение - он указывает NuGet, что файлы в каталоге должны использоваться на любой платформе, с которой совместимы все ваши зависимости пакетов. Таким образом, ваш пакет автоматически используется на любой платформе .NET, которая поддерживает все ваши зависимости (например,.NET Core).

Ключевым следующим шагом является определение списка зависимостей. Из-за проблемы управления пакетами невозможно просто объявить зависимость от самого .NET Core (.NET Core - это поверхность API, доступная всем платформам .NET), Вместо этого вы должны вручную определить каждую зависимость компонента .NET Core и добавить ее в файл nuspec.

Процесс обнаружения зависимостей для пакетов .NET Core состоит из двух шагов:

  • Определите сборки .NET Core, на которые ссылается ваша библиотека.
  • Определите пакеты NuGet, содержащие эти сборки.

Visual Studio не предоставляет необходимую информацию. Вместо этого вам нужно создать свою библиотеку и проверить полученный DLL файл. Следующий PowerShell script отобразит ссылки сборки .NET:

Get-ChildItem MyPortableLibrary.dll | % { [Reflection.Assembly]::LoadFile($_.FullName).GetReferencedAssemblies() | % { $_.Name + ".dll" } }

Результатом этой команды будет список имен сборки, например:

System.Runtime.dll
System.Resources.ResourceManager.dll
System.Numerics.Vectors.dll

Как только вы получили список, откройте файл project.lock.json в каталоге проекта. Этот файл содержит информацию обо всех пакетах NuGet, используемых вашим проектом. Вы найдете среди других данных различные блоки JSON, такие как:

"System.Numerics.Vectors/4.1.0": {
    "dependencies": {
        "System.Globalization": "[4.0.10, )",
        "System.Resources.ResourceManager": "[4.0.0, )",
        "System.Runtime": "[4.0.20, )",
        "System.Runtime.Extensions": "[4.0.10, )"
    },
    "frameworkAssemblies": [
        "mscorlib",
        "System.Numerics"
    ],
    "compile": {
        "ref/net46/System.Numerics.Vectors.dll": {}
    },
    "runtime": {
        "lib/net46/System.Numerics.Vectors.dll": {}
    }
},

Этот блок JSON указывает, что файлы сборки, перечисленные в разделе "компиляция", предоставляются пакетом, указанным в верхнем уровне (System.Numerics.Vectors версии 4.1.0). Используйте эту информацию для сопоставления каждой ссылочной сборки с пакетом NuGet. Обратите внимание, что, хотя имена пакетов и сборок часто совпадают, это не всегда так!

Для любых пакетов NuGet, которые не являются частью .NET Core, вы можете пропустить вышеуказанный процесс, поскольку вы уже знаете точный пакет, на который у вас есть зависимость. Логика обнаружения зависимостей, описанная здесь, требуется только потому, что вы не можете объявлять зависимость непосредственно на .NET Core (пакет Microsoft.NETCore) из-за проблемы, связанной выше.

Теперь просто перечислите все зависимости в вашем файле nuspec на следующем примере:

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <metadata minClientVersion="3.2">
        <id>Example.MyPortableLibrary</id>
        <version>1.0.0</version>
        <authors>Firstname Lastname</authors>
        <description>Example of a portable library with NuGet package dependencies.</description>
        <dependencies>
            <dependency id="System.Numerics.Vectors" version="4.1.0" />
            <dependency id="System.Resources.ResourceManager" version="4.0.0" />
            <dependency id="System.Runtime" version="4.0.20" />
        </dependencies>
    </metadata>
    <files>
        <file src="..\bin\Release\MyPortableLibrary.*" target="lib\dotnet" />
    </files>
</package>

Что это! Получаемый пакет можно использовать на любой совместимой платформе .NET, такой как .NET Framework 4.6 или Universal Windows Platform. Не забудьте создать свое решение с помощью конфигурации Release перед созданием пакета NuGet.

Библиотека образцов и соответствующие упаковочные файлы доступна на GitHub. Решение, соответствующее этому ответу, - PortableLibrary.

Обратитесь к блогу Lucian Wischik за более глубокое погружение в логику, которая работает с такими пакетами NuGet.

Ответ 2

Похоже, что за последние несколько месяцев появилось много попыток создать переносные библиотеки .NET framework/пакеты NuGet. Если вы можете немного подождать, вы захотите ознакомиться с .NET Standard. Immo Landwerth написал подробное сообщение в котором сообщается о стандарте .NET в сентябре 2016 года. Поддержка .NET Standard 2.0 в .NET Core ожидается в начале 2017 года, в тот же промежуток времени, что и Visual Studio 2017, который в настоящее время находится в Release Candidate..NET Standard 2.0 будет реализован .NET Framework,.NET Core и Xamarin. Он также будет включать совместимые прокладки для двоичных файлов .NET Framework, которые должны упростить принятие.

Update:

Oren Novotny имеет очень информативное сообщение в блоге на эту тему: Multi-targeting the world: единый проект, чтобы управлять ими всеми. Он обсуждает .NET Standard и как многоцелевую визуализацию с Visual Studio 2017. Сообщение в блоге было до RTM Visual Studio 2017, но это очень полезно.