使用 Visual Studio 2017 或 2019 为 Xamarin 创建包

Xamarin 包包含在 iOS、Android 和 Windows 上使用本机 API 的代码,具体取决于运行时操作系统。 虽然这很简单,但最好让开发人员通过通用的 API 外围应用从 PCL 或 .NET Standard 库中使用包。

在本演练中,将使用 Visual Studio 2017 或 2019 创建可在 iOS、Android 和 Windows 的移动项目中使用的跨平台 NuGet 包。

  1. 先决条件
  2. 创建项目结构和抽象代码
  3. 编写平台特定的代码
  4. 创建并更新 .nuspec 文件
  5. 打包组件
  6. 相关主题

先决条件

  1. 在通用 Windows 平台 (UWP) 和 Xamarin 中使用 Visual Studio 2017 或 2019。 可以从 visualstudio.com 免费安装 Community 版;当然,也可以使用 Professional 和 Enterprise 版。 若要包含 UWP 和 Xamarin 工具,请选择自定义安装并选中相应的选项。
  2. NuGet CLI。 从 nuget.org/downloads 下载 nuget.exe 的最新版本,将其保存到选择的位置。 然后将该位置添加到 PATH 环境变量(如果尚未添加)。

注意

nuget.exe 是 CLI 工具本身,不是安装程序,因此一定要保存从浏览器下载的文件,而非运行。

创建项目结构和抽象代码

  1. 下载并运行适用于 Visual Studio 的跨平台 .NET Standard 插件模板扩展。 使用这些模板可轻松创建本演练所需的项目结构。

  2. 在 Visual Studio 2017 中,文件>新建>Project,搜索Plugin,选择跨平台 .NET 标准库插件模板,将名称更改为 LoggingLibrary,然后单击“确定”。

    New Blank App (Xamarin.Forms Portable) project in VS 2017

    在 Visual Studio 2019 中,文件>新建>Project,搜索Plugin,选择跨平台 .NET 标准库插件模板,然后单击“下一步”。

    New Blank App (Xamarin.Forms Portable) project in VS 2019

    将名称更改为 LoggingLibrary,然后单击“创建”。

    New Blank App (Xamarin.Forms Portable) configuration in VS 2019

生成的解决方案包含两个共享项目,以及各种平台特定的项目:

  • ILoggingLibrary 项目,该项目包含在 ILoggingLibrary.shared.cs 文件中,用于定义组件的公共接口(API 外围应用)。 你将在此文件中定义库的接口。
  • 另一个共享项目包含 CrossLoggingLibrary.shared.cs 中的代码,这些代码将在运行时定位抽象接口的平台特定实现。 通常不需要修改此文件。
  • 特定于平台的项目(例如 LoggingLibrary.android.cs,每个项目)在其各自的 LoggingLibraryImplementation.cs (VS 2017) 或 LoggingLibrary.<PLATFORM>.cs (VS 2019) 文件中都包含接口的本机实现。 你将在此文件中生成库的代码。

默认情况下,ILoggingLibrary 项目的 ILoggingLibrary.shared.cs 文件包含接口定义,但不包含方法。 为进行本演练,请按如下所示添加 Log 方法:

using System;
using System.Collections.Generic;
using System.Text;

namespace Plugin.LoggingLibrary
{
    /// <summary>
    /// Interface for LoggingLibrary
    /// </summary>
    public interface ILoggingLibrary
    {
        /// <summary>
        /// Log a message
        /// </summary>
        void Log(string text);
    }
}

编写平台特定的代码

若要实现 ILoggingLibrary 接口及其方法的平台特定实现,请执行以下操作:

  1. 打开每个平台项目的 LoggingLibraryImplementation.cs (VS 2017) 或 LoggingLibrary.<PLATFORM>.cs (VS 2019) 文件并添加必要的代码。 例如(使用 Android 平台项目):

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Plugin.LoggingLibrary
    {
        /// <summary>
        /// Implementation for Feature
        /// </summary>
        public class LoggingLibraryImplementation : ILoggingLibrary
        {
            /// <summary>
            /// Log a message
            /// </summary>
            public void Log(string text)
            {
                throw new NotImplementedException("Called Log on Android");
            }
        }
    }
    
  2. 在想要支持的每个平台的项目中重复此实现。

  3. 右键单击解决方案,选择“生成解决方案”,检查工作并生成接下来将要打包的项目。 如果遇到关于缺少引用的错误,请右键单击解决方案,选择“还原 NuGet 包”,安装依赖项并重新生成

注意

如果使用的是 Visual Studio 2019,则在选择“还原 NuGet 包”并尝试重新生成之前,需要将 MSBuild.Sdk.Extras 的版本更改为 LoggingLibrary.csproj 中的 2.0.54。 只能通过以下方式访问此文件:首先右键单击该项目(在解决方案下方)并选择 Unload Project,然后右键单击卸载的项目并选择 Edit LoggingLibrary.csproj

注意

若要为 iOS 生成,需要一台连接到 Visual Studio 的联网 Mac,如 Introduction to Xamarin.iOS for Visual Studio(Xamarin.iOS for Visual Studio 简介)中所述。 如果没有可用的 Mac,请清除配置管理器中的 iOS 项目(上面的步骤 3)。

创建并更新 .nuspec 文件

  1. 打开命令提示符,导航到 .sln 文件下一级的 LoggingLibrary 文件夹,然后运行 NuGet spec 命令,创建初始 Package.nuspec 文件:

    nuget spec
    
  2. 将该文件重命名为 LoggingLibrary.nuspec 并在编辑器中打开。

  3. 将文件更新为与以下内容匹配,并将 YOUR_NAME 替换为适当的值。 具体而言,<id> 值在 nuget.org 中必须是唯一的(请参阅创建包中所述的命名约定)。 另请注意,还必须更新创建者和说明标记,否则在打包步骤中会出现错误。

    <?xml version="1.0"?>
    <package >
        <metadata>
        <id>LoggingLibrary.YOUR_NAME</id>
        <version>1.0.0</version>
        <title>LoggingLibrary</title>
        <authors>YOUR_NAME</authors>
        <owners>YOUR_NAME</owners>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>Awesome application logging utility</description>
        <releaseNotes>First release</releaseNotes>
        <copyright>Copyright 2018</copyright>
        <tags>logger logging logs</tags>
        </metadata>
    </package>
    

提示

可使用 -alpha-beta-rc 为包版本添加后缀,将包标记为预发行版本,有关预发行版本的详细信息,请查阅预发行版本

添加引用程序集

若要包含平台特定的引用程序集,请将以下内容添加到 LoggingLibrary.nuspec<files> 元素,以适用于支持的平台:

<!-- Insert below <metadata> element -->
<files>
    <!-- Cross-platform reference assemblies -->
    <file src="Plugin.LoggingLibrary\bin\Release\Plugin.LoggingLibrary.dll" target="lib\netstandard1.4\Plugin.LoggingLibrary.dll" />
    <file src="Plugin.LoggingLibrary\bin\Release\Plugin.LoggingLibrary.xml" target="lib\netstandard1.4\Plugin.LoggingLibrary.xml" />
    <file src="Plugin.LoggingLibrary.Abstractions\bin\Release\Plugin.LoggingLibrary.Abstractions.dll" target="lib\netstandard1.4\Plugin.LoggingLibrary.Abstractions.dll" />
    <file src="Plugin.LoggingLibrary.Abstractions\bin\Release\Plugin.LoggingLibrary.Abstractions.xml" target="lib\netstandard1.4\Plugin.LoggingLibrary.Abstractions.xml" />

    <!-- iOS reference assemblies -->
    <file src="Plugin.LoggingLibrary.iOS\bin\Release\Plugin.LoggingLibrary.dll" target="lib\Xamarin.iOS10\Plugin.LoggingLibrary.dll" />
    <file src="Plugin.LoggingLibrary.iOS\bin\Release\Plugin.LoggingLibrary.xml" target="lib\Xamarin.iOS10\Plugin.LoggingLibrary.xml" />

    <!-- Android reference assemblies -->
    <file src="Plugin.LoggingLibrary.Android\bin\Release\Plugin.LoggingLibrary.dll" target="lib\MonoAndroid10\Plugin.LoggingLibrary.dll" />
    <file src="Plugin.LoggingLibrary.Android\bin\Release\Plugin.LoggingLibrary.xml" target="lib\MonoAndroid10\Plugin.LoggingLibrary.xml" />

    <!-- UWP reference assemblies -->
    <file src="Plugin.LoggingLibrary.UWP\bin\Release\Plugin.LoggingLibrary.dll" target="lib\UAP10\Plugin.LoggingLibrary.dll" />
    <file src="Plugin.LoggingLibrary.UWP\bin\Release\Plugin.LoggingLibrary.xml" target="lib\UAP10\Plugin.LoggingLibrary.xml" />
</files>

注意

若要缩短 DLL 和 XML 文件的名称,请右键单击任何给定项目,选择“库”选项卡,然后更改程序集名称

添加依赖项

如果有特定的本机实现依赖项,请使用带有 <group> 元素的 <dependencies> 元素来指定它们,例如:

<!-- Insert within the <metadata> element -->
<dependencies>
    <group targetFramework="MonoAndroid">
        <!--MonoAndroid dependencies go here-->
    </group>
    <group targetFramework="Xamarin.iOS10">
        <!--Xamarin.iOS10 dependencies go here-->
    </group>
    <group targetFramework="uap">
        <!--uap dependencies go here-->
    </group>
</dependencies>

例如,以下代码用于将 iTextSharp 设置为 UAP 目标的依赖项:

<dependencies>
    <group targetFramework="uap">
        <dependency id="iTextSharp" version="5.5.9" />
    </group>
</dependencies>

最终 .nuspec

现在,最终 .nuspec 文件应该如下所示,其中应再次将 YOUR_NAME 替换为适当的值:

<?xml version="1.0"?>
<package >
    <metadata>
    <id>LoggingLibrary.YOUR_NAME</id>
    <version>1.0.0</version>
    <title>LoggingLibrary</title>
    <authors>YOUR_NAME</authors>
    <owners>YOUR_NAME</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Awesome application logging utility</description>
    <releaseNotes>First release</releaseNotes>
    <copyright>Copyright 2018</copyright>
    <tags>logger logging logs</tags>
        <dependencies>
        <group targetFramework="MonoAndroid">
            <!--MonoAndroid dependencies go here-->
        </group>
        <group targetFramework="Xamarin.iOS10">
            <!--Xamarin.iOS10 dependencies go here-->
        </group>
        <group targetFramework="uap">
            <dependency id="iTextSharp" version="5.5.9" />
        </group>
    </dependencies>
    </metadata>
    <files>
        <!-- Cross-platform reference assemblies -->
        <file src="Plugin.LoggingLibrary\bin\Release\Plugin.LoggingLibrary.dll" target="lib\netstandard1.4\Plugin.LoggingLibrary.dll" />
        <file src="Plugin.LoggingLibrary\bin\Release\Plugin.LoggingLibrary.xml" target="lib\netstandard1.4\Plugin.LoggingLibrary.xml" />
        <file src="Plugin.LoggingLibrary.Abstractions\bin\Release\Plugin.LoggingLibrary.Abstractions.dll" target="lib\netstandard1.4\Plugin.LoggingLibrary.Abstractions.dll" />
        <file src="Plugin.LoggingLibrary.Abstractions\bin\Release\Plugin.LoggingLibrary.Abstractions.xml" target="lib\netstandard1.4\Plugin.LoggingLibrary.Abstractions.xml" />

        <!-- iOS reference assemblies -->
        <file src="Plugin.LoggingLibrary.iOS\bin\Release\Plugin.LoggingLibrary.dll" target="lib\Xamarin.iOS10\Plugin.LoggingLibrary.dll" />
        <file src="Plugin.LoggingLibrary.iOS\bin\Release\Plugin.LoggingLibrary.xml" target="lib\Xamarin.iOS10\Plugin.LoggingLibrary.xml" />

        <!-- Android reference assemblies -->
        <file src="Plugin.LoggingLibrary.Android\bin\Release\Plugin.LoggingLibrary.dll" target="lib\MonoAndroid10\Plugin.LoggingLibrary.dll" />
        <file src="Plugin.LoggingLibrary.Android\bin\Release\Plugin.LoggingLibrary.xml" target="lib\MonoAndroid10\Plugin.LoggingLibrary.xml" />

        <!-- UWP reference assemblies -->
        <file src="Plugin.LoggingLibrary.UWP\bin\Release\Plugin.LoggingLibrary.dll" target="lib\UAP10\Plugin.LoggingLibrary.dll" />
        <file src="Plugin.LoggingLibrary.UWP\bin\Release\Plugin.LoggingLibrary.xml" target="lib\UAP10\Plugin.LoggingLibrary.xml" />
    </files>
</package>

打包组件

如果已完成的 .nuspec 引用需要包含在包中的所有文件,便可运行 pack 命令:

nuget pack LoggingLibrary.nuspec

这将生成 LoggingLibrary.YOUR_NAME.1.0.0.nupkg。 在类似 NuGet 包资源管理器的工具中打开此文件并展开所有节点,即可看到以下内容:

NuGet Package Explorer showing the LoggingLibrary package

提示

.nupkg 文件实际上是具有其他扩展名的 ZIP 文件。 然后,也可通过将 .nupkg 更改为 .zip 来检查包内容,但将包上传到 nuget.org 之前,请记得恢复扩展名。

若要使程序包可供其他开发人员使用,请按照有关 发布包的说明进行操作。