教程:创建模板包

使用 .NET,可以创建和部署可生成项目、文件甚至资源的模板。 本教程是系列教程的第三部分,介绍如何创建、安装和卸载用于 dotnet new 命令的模板。

可以在 .NET 示例 GitHub 存储库中查看已完成的模板。

在本系列的这一部分中,你将了解如何:

  • 创建一个 *.csproj 项目以生成模板包。
  • 配置项目文件以进行打包。
  • 从 NuGet 包文件安装模板包。
  • 按包 ID 卸载模板包。

先决条件

  • 完成本系列教程的第 1 部分第 2 部分

    本教程使用本教程系列前两部分中创建的两个模板。 只要将不同的模板作为文件夹复制到 working\content 文件夹中,就可以使用该模板。

  • 打开终端并导航到工作文件夹

  • 安装 .NET 8。

  • 从 NuGet 包源安装 Microsoft.TemplateEngine.Authoring.Templates 模板。

    • 从终端运行 dotnet new install Microsoft.TemplateEngine.Authoring.Templates 命令。

重要

本文针对 .NET 7 编写。 但是,它也适用于 .NET 6 和早期版本,但有一个区别:dotnet new 语法不同。 listsearchinstalluninstall 子命令应分别为 --list--search--install--uninstall 选项。

例如,.NET 7 中的 dotnet new install 命令在 .NET 6 中变为 dotnet new --install。 使用 dotnet new --help 命令查看所有选项和子命令的列表。

创建模板包项目

模板包是打包到 NuGet 包中的一个或多个模板。 安装或卸载模板包时,将分别添加或删除包中包含的所有模板。

模板包由 NuGet 包 (.nupkg) 文件表示。 并且,与任何 NuGet 包一样,可以将模板包上传到 NuGet 源。 dotnet new install 命令支持从 NuGet 包源(一个 .nupkg 文件)或包含模板的目录安装模板包

通常情况下,使用 C# 项目文件来编译代码并生成二进制文件。 但是,该项目也可用于生成模板包。 通过更改 .csproj 的设置,可以阻止它编译任何代码,而是将模板的所有资产都包含在内作为资源。 生成此项目后,它会生成模板包 NuGet 包。

要生成的包将包含之前创建的 [item] 和 (cli-templates-create-item-template.md) 以及项目模板。

Microsoft.TemplateEngine.Authoring.Templates 包包含可用于创作模板的模板。 若要安装此包,nuget.org 作为工作目录中的 NuGet 源提供。

  1. 在工作文件夹中,运行以下命令以创建模板包

    dotnet new templatepack -n "AdatumCorporation.Utility.Templates"
    

    -n 参数将项目文件名设置为 AdatumCorporation.Utility.Templates.csproj。 应看到类似于以下输出的结果。

    The template "Template Package" was created successfully.
    
    Processing post-creation actions...
    Description: Manual actions required
    Manual instructions: Open *.csproj in the editor and complete the package metadata configuration. Copy the templates to _content_ folder. Fill in README.md.
    
  2. 接下来,在代码编辑器中打开 AdatumCorporation.Utility.Templates.csproj 文件,并根据模板中的提示填充该文件

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <!-- The package metadata. Fill in the properties marked as TODO below -->
        <!-- Follow the instructions on https://learn.microsoft.com/nuget/create-packages/package-authoring-best-practices -->
        <PackageId>AdatumCorporation.Utility.Templates</PackageId>
        <PackageVersion>1.0</PackageVersion>
        <Title>AdatumCorporation Templates</Title>
        <Authors>Me</Authors>
        <Description>Templates to use when creating an application for Adatum Corporation.</Description>
        <PackageTags>dotnet-new;templates;contoso</PackageTags>
        <PackageProjectUrl>https://your-url</PackageProjectUrl>
    
        <PackageType>Template</PackageType>
        <TargetFramework>net8.0</TargetFramework>
        <IncludeContentInPack>true</IncludeContentInPack>
        <IncludeBuildOutput>false</IncludeBuildOutput>
        <ContentTargetFolders>content</ContentTargetFolders>
        <NoWarn>$(NoWarn);NU5128</NoWarn>
        <NoDefaultExcludes>true</NoDefaultExcludes>
        ... cut for brevity ...
    
  1. 在工作文件夹中,运行以下命令以创建模板包

    dotnet new console -n AdatumCorporation.Utility.Templates
    

    -n 参数将项目文件名设置为 AdatumCorporation.Utility.Templates.csproj。 应看到类似于以下输出的结果。

    The template "Console Application" was created successfully.
    
    Processing post-creation actions...
    Running 'dotnet restore' on .\AdatumCorporation.Utility.Templates.csproj...
      Restore completed in 52.38 ms for C:\code\working\AdatumCorporation.Utility.Templates.csproj.
    
    Restore succeeded.
    
  2. 删除 Program.cs 文件。 新项目模板将生成此文件,但模板引擎不会使用它。

  3. 接下来,在你偏好的编辑器中打开 AdatumCorporation.Utility.Templates.csproj 文件,并将内容替换为以下 XML

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <PackageId>AdatumCorporation.Utility.Templates</PackageId>
        <PackageVersion>1.0</PackageVersion>
        <Title>AdatumCorporation Templates</Title>
        <Authors>Me</Authors>
        <Description>Templates to use when creating an application for Adatum Corporation.</Description>
        <PackageTags>dotnet-new;templates;adatum</PackageTags>
        <PackageProjectUrl>https://your-url</PackageProjectUrl>
    
        <PackageType>Template</PackageType>
        <TargetFramework>netstandard2.0</TargetFramework>
        <IncludeContentInPack>true</IncludeContentInPack>
        <IncludeBuildOutput>false</IncludeBuildOutput>
        <ContentTargetFolders>content</ContentTargetFolders>
        <NoWarn>$(NoWarn);NU5128</NoWarn>
        <NoDefaultExcludes>true</NoDefaultExcludes>
      </PropertyGroup>
    
      <ItemGroup>
        <Content Include="content\**\*" Exclude="content\**\bin\**;content\**\obj\**" />
        <Compile Remove="**\*" />
      </ItemGroup>
    
    </Project>
    

项目 XML 的说明

XML 代码片段中 <PropertyGroup> 下的设置分为两组。

第一组处理 NuGet 包所需的属性。 四个 <Package*> 设置与 NuGet 包属性相关,用于在 NuGet 源上标识你的包。 <PackageId> 值虽然由 NuGet 使用,但也可用于卸载模板包。 其余设置(例如 <Title><PackageTags>)与 NuGet 源和 .NET 包管理器中显示的元数据相关。 有关 NuGet 设置的详细信息,请参阅 NuGet 和 MSBuild 属性

注意

若要确保模板包显示在 dotnet new search 结果中,必须将 <PackageType> 设置为 Template

在第二组中,<TargetFramework> 设置可确保在你运行 pack 命令以编译和打包项目时,MSBuild 可以正常运行。 该组还包括与配置项目有关的设置,可以在创建 NuGet 包时将模板包含在该包内的相应文件夹中:

  • <NoWarn> 设置可用于取消不适用于模板包项目的警告消息。

  • <NoDefaultExcludes> 设置可确保以 .(如 .gitignore)开头的文件和文件夹是模板的一部分。 NuGet 包的默认行为是忽略这些文件和文件夹。

<ItemGroup> 包含两个项。 首先,<Content> 项的内容包含 templates 文件夹中的所有内容。 它还设置为排除任何 bin 文件夹或 obj 文件夹,以防止包含任何已编译的代码(如果已测试和编译模板)。 其次,<Compile> 项将所有代码文件排除在编译范围之外,无论它们位于何处都是如此。 此设置可阻止用于创建模板包的项目尝试编译 templates 文件夹层次结构中的代码。

提示

有关 NuGet 元数据设置的详细信息,请参阅将模板打包到 NuGet 包(nupkg 文件)中

创建的项目文件包括模板创作 MSBuild 任务和本地化设置。

  <PropertyGroup>
    <LocalizeTemplates>false</LocalizeTemplates>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.TemplateEngine.Tasks" Version="*" PrivateAssets="all" IsImplicitlyDefined="true"/>
  </ItemGroup>

重要

content 内容文件夹包含一个 SampleTemplate 文件夹。 请删除此文件夹,因为它是出于演示目的而添加到创作模板中的

这些 MSBuild 任务提供模板验证和模板本地化功能。 默认情况下,本地化功能处于禁用状态。 若要启用本地化文件的创建,请将 LocalizeTemplates 设置为 true

打包并安装

保存项目文件。 在生成模板包之前,请验证文件夹结构是否正确。 要打包的任何模板都应放置在自己的文件夹中的 templates 文件夹中。 文件夹结构应类似于以下层次结构:

working
│   AdatumCorporation.Utility.Templates.csproj
└───content
    ├───extensions
    │   └───.template.config
    │           template.json
    └───consoleasync
        └───.template.config
                template.json

content 文件夹中有两个文件夹:extensionsconsoleasync

在终端中的 working 文件夹中,运行 dotnet pack 命令。 此命令会生成项目,并在 working\bin\Debug 文件夹中创建一个 NuGet 包,如以下输出所示

MSBuild version 17.8.0-preview-23367-03+0ff2a83e9 for .NET
  Determining projects to restore...
  Restored C:\code\working\AdatumCorporation.Utility.Templates.csproj (in 1.16 sec).

  AdatumCorporation.Utility.Templates -> C:\code\working\bin\Release\net8.0\AdatumCorporation.Utility.Templates.dll
  Successfully created package 'C:\code\working\bin\Release\AdatumCorporation.Utility.Templates.1.0.0.nupkg'.

接下来,使用 dotnet new install 命令安装模板包。 在 Windows 上:

dotnet new install .\bin\Release\AdatumCorporation.Utility.Templates.1.0.0.nupkg

在 Linux 或 macOS 上:

dotnet new install bin/Release/AdatumCorporation.Utility.Templates.1.0.0.nupkg

应该会看到与下面类似的输出:

The following template packages will be installed:
   C:\code\working\AdatumCorporation.Utility.Templates\bin\Release\AdatumCorporation.Utility.Templates.1.0.0.nupkg

Success: AdatumCorporation.Utility.Templates::1.0.0 installed the following templates:
Templates                                         Short Name               Language          Tags
--------------------------------------------      -------------------      ------------      ----------------------
Example templates: string extensions              stringext                [C#]              Common/Code
Example templates: async project                  consoleasync             [C#]              Common/Console/C#9

如果将 NuGet 包上传到 NuGet 源,可以使用 dotnet new install <PACKAGE_ID> 命令,其中,<PACKAGE_ID> 与 .csproj 文件中的 <PackageId> 设置相同。

卸载模板包

无论如何安装模板包,即无论是直接使用 .nupkg 文件还是通过 NuGet 源安装,删除模板包的操作都是一样的。 使用要卸载的模板的 <PackageId>。 可以通过运行 dotnet new uninstall 命令获取已安装的模板列表。

C:\working> dotnet new uninstall
Currently installed items:
... cut to save space ...

  AdatumCorporation.Utility.Templates
    Details:
      NuGetPackageId: AdatumCorporation.Utility.Templates
      Version: 1.0.0
      Author: Me
    Templates:
      Example templates: async project (consoleasync) C#
      Example templates: string extensions (stringext) C#
    Uninstall Command:
      dotnet new uninstall AdatumCorporation.Utility.Templates

运行 dotnet new uninstall AdatumCorporation.Utility.Templates 以卸载模板包。 该命令输出有关卸载了哪些模板包的信息。

祝贺你! 你已完成模板包的安装和卸载操作。

后续步骤

若要了解有关模板的详细信息(你已经了解了大部分相关信息),请参阅为 dotnet new 自定义模板一文。