如何打包针对.NET Core的可移植.NET库? [英] How to package a portable .NET library targeting .NET Core?

查看:101
本文介绍了如何打包针对.NET Core的可移植.NET库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何以现代通用方式打包可移植.NET库?假设我有一个AnyCPU程序集,希望对支持.NET Core API表面的任何.NET平台(例如.NET Framework 4.6和通用Windows平台)可用。

How do I package a portable .NET library in a modern general-purpose way? Let's assume I have a single AnyCPU assembly that I wish to make available to any .NET platform that supports the .NET Core API surface, for example .NET Framework 4.6 and the Universal Windows Platform.


这是一系列问答,记录了我对现代NuGet程序包创作这一主题的发现,尤其着重于NuGet 3引入的更改。您可能还对某些内容感兴趣相关问题:

This is a series of questions and answers that document my findings on the topic of modern NuGet package authoring, focusing especially on the changes introduced with NuGet 3. You may also be interested in some related questions:

  • How to package a .NET Framework library?
  • How to package a .NET library targeting the Universal Windows Platform?
  • How to package a .NET library targeting .NET Framework and Universal Windows Platform and include platform-specific functionality?
  • How to package a multi-architecture .NET library that targets the Universal Windows Platform?
  • How to package a .NET library that targets the Universal Windows Platform and depends on Visual Studio extension SDKs?


推荐答案

此答案基于用于打包针对.NET Framework的库的原理。首先阅读链接的答案,以更好地理解以下内容。

This answer builds upon the principles used to package libraries targeting the .NET Framework. Read the linked answer first to better understand the following.

要发布可移植的.NET库,您将需要创建具有以下结构的NuGet包:

To publish the portable .NET library, you will need to create a NuGet package with the following structure:

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

所有三个文件都来自项目的build输出目录下发行版本配置。

All three files will come from your project's build output directory under the Release build configuration.

以上结构中的 dotnet 目录具有特殊含义-它向NuGet指示该目录中的文件将在与包的所有依赖项都兼容的任何平台上使用。因此,您的程序包可在支持所有依赖项的任何.NET平台(例如.NET Core)上自动使用。

The dotnet directory in the structure above has a special meaning - it indicates to NuGet that the files in the directory are to be used on any platform that all your package's dependencies are compatible with. Therefore, your package is automatically usable on any .NET platform that supports all your dependencies (e.g. .NET Core).

关键的下一步是确定依赖项列表。由于包管理问题,无法简单地声明对.NET Core本身的依赖关系(.NET Core是所有.NET平台共享的API界面)。而是必须手动确定每个.NET Core组件依赖项,并将其添加到nuspec文件中。

The crucial next step is to determine the list of dependencies. Due to a package management issue it is not possible to simply declare a dependency on .NET Core itself (.NET Core is the API surface shared by all the .NET platforms). Instead, you must manually determine each .NET Core component dependency and add it to the nuspec file.

.NET Core包的依赖项检测过程包括两个步骤:

The dependency detection process for .NET Core packages consists of two steps:


  1. 确定库引用的.NET Core程序集。

  2. 确定包含这些库的NuGet程序包

Visual Studio不提供您所需的信息。相反,您需要构建库并检查生成的DLL文件。以下PowerShell脚本将显示.NET程序集的引用:

Visual Studio does not provide the information you need. Instead, you need to build your library and inspect the resulting DLL file. The following PowerShell script will display the references of a .NET assembly:

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

此命令的输出为程序集名称列表,例如:

The output of this command will be a list of assembly names, for example:

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

获得列表后,打开project.lock项目目录中的.json文件。该文件包含有关项目使用的所有NuGet软件包的信息。在其他数据中,您将找到JSON的各种块,例如:

Once you have obtained the list, open the project.lock.json file in your project directory. This file contains information about all NuGet packages used by your project. You will find, among other data, various blocks of JSON such as the following:

"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块指示提供了 compile下列出的程序集文件按顶级值中列出的程序包(System.Numerics.Vectors版本4.1.0)。使用此信息将每个引用的程序集映射到NuGet包。请注意,尽管程序包和程序集的名称通常相同,但并非总是如此!

This block of JSON indicates that the assembly files listed under "compile" are provided by the package listed in the top level value (System.Numerics.Vectors version 4.1.0). Use this information to map every referenced assembly to a NuGet package. Note that while the package and assembly names are often the same, this is not always the case!

对于不属于.NET Core的任何NuGet程序包,您都可以因为您已经知道依赖的确切软件包,所以跳过上述过程。此处描述的依赖关系检测逻辑仅是必需的,因为由于上面链接的问题,您不能直接在.NET Core(Microsoft.NETCore程序包)上声明依赖关系。

For any NuGet packages that are not part of .NET Core, you can skip the above process as you already know the exact package you have a dependency on. The dependency detection logic described here is only required because you cannot declare a dependency directly on .NET Core (the Microsoft.NETCore package) due to the issue linked above.

现在只需根据以下示例列出nuspec文件中的所有依赖项:

Now simply list all the dependencies in your nuspec file, based on the following example:

<?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。在创建NuGet软件包之前,请记住使用Release配置来构建您的解决方案。

That's it! The resulting package is usable on any compatible .NET platform, such as .NET Framework 4.6 or Universal Windows Platform. Remember to build your solution using the Release configuration before creating the NuGet package.

示例库和相关打包文件为在GitHub上可用。与此答案对应的解决方案是PortableLibrary。

A sample library and the relevant packaging files are available on GitHub. The solution corresponding to this answer is PortableLibrary.

请参考Lucian Wischik的博客深入探讨了在此类NuGet软件包上运行的逻辑。

Refer to Lucian Wischik's blog for a deeper dive into the logic that operates on such NuGet packages.

这篇关于如何打包针对.NET Core的可移植.NET库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆