作者的.NET模板

作为模板作者,可以创建.NET模板-蓝图,用于从预定义结构生成项目、文件或其他资源。 用户运行时dotnet new <shortName>,.NET模板引擎读取模板并在当前目录中生成输出。 Visual Studio的“创建新项目”对话框还对.NET项目模板使用.NET模板引擎,因此为 CLI 创作的模板也在Visual Studio中工作。

.NET SDK 附带了内置模板,用于常见起点,例如控制台应用、类库和 ASP.NET 项目。 除了这些内置模板之外,还可以创作自己的模板并将其分发为 NuGet 包。

本文是模板作者的参考。 其中介绍了模板的结构化、配置和分布方式。 有关创建和打包模板的分步说明,请参阅 “相关内容 ”部分。

模板类型

.NET模板引擎支持三种类型的模板:项模板、项目模板和解决方案模板。

  • 项目模板 生成一个或多个文件,例如代码文件、配置文件或其他资源,而无需围绕它们生成整个项目。 例如,项模板可能会生成一个类文件,该文件添加一组扩展方法,或遵循团队使用的标准布局的 JSON 配置文件。 若要了解如何生成项模板,请参阅 教程:创建项模板。

  • Project模板生成完整的project结构。 例如,内置控制台项目模板生成一个 .csproj 文件、一个 Program.cs 文件和构成该项目的任何其他文件。 如果要向用户提供完整的项目起点而不是单个文件,请创作项目模板。 若要了解如何生成项目模板,请参阅 教程:创建项目模板。

  • 解决方案模板 生成包含一个或多个项目的解决方案。 例如,解决方案模板可以在单个步骤中创建与测试项目配对的 API 项目。

创建自己的模板时,可以使用配置文件中的template.json字段声明其类型tags.type。 有效值为 "project"、"item"和 "solution"。 这些值允许用户在搜索包含 dotnet new search 或的 dotnet new list模板时筛选结果。

Tip

Project和解决方案模板显示在Visual Studio“创建新project”对话框中,但项模板不会显示在“添加新>项”对话框中。 用户可以从 dotnet new CLI 访问项模板。

模板结构

模板是磁盘上的一个文件夹,其中包含两项内容:模板源文件和特殊 .template.config 子文件夹。 当用户运行时 dotnet new <shortName>,模板引擎会将源文件复制到输出位置,并应用为模板定义的任何配置。

mytemplate/
├── console.cs
├── readme.txt
└── .template.config/
    ├── template.json
    └── icon.png

源文件可以是任何类型的文件。 模板引擎不需要将特殊令牌或标记注入源代码。 它使用 as-is文件,这意味着你可以生成、运行和调试模板的源项目,就像普通.NET项目一样。 若要将现有项目转换为模板,请将 .template.config/template.json 文件添加到项目根目录。

可以选择将绑定到模板参数(符号)的替换令牌直接注入模板源文件和文件名。 如果令牌无效,则无法在将其部署为模板之前生成、运行或调试源项目。 令牌不会影响用户从已部署模板创建的项目,因为模板引擎会在项目创建过程中替换它们。

内部 .template.config 唯一必需的文件是 template.json。 该文件告知模板引擎它所需的一切:模板的名称、短名称、作者、分类以及用户可以从模板创建时传递的任何参数。 还可以将.template.config文件icon.png放在文件夹中。 终端不显示图标,但Visual Studio显示“创建新项目”对话框中模板旁边的图标。 128×128 PNG 效果良好。

template.json 文件

该文件 template.json 是模板中唯一必需的配置部分。 它位于文件夹内 .template.config ,并告知模板引擎如何呈现和处理模板。 下表描述了常见的必需字段和可选字段:

领域 类型 必选 Description
$schema URI 否 的 template.jsonJSON 架构。 https://json.schemastore.org/template设置为在编辑器(如 Visual Studio Code)中启用 IntelliSense。
author 字符串 否 模板的作者。
classifications array(string) 否 标记用户可用于查找模板或 dotnet new searchdotnet new list. 这些值显示在模板列表的 “标记” 列中。
description 字符串 否 模板创建的内容的说明。
identity 字符串 是的 模板的唯一标识符。
name 字符串 是的 向用户显示的模板的显示名称。
shortName 字符串 是的 用户传递给 dotnet new 从模板创建的短名称,例如 console 或 classlib。
sourceName 字符串 否 源文件和文件名中的字符串,模板引擎将替换为用户通过 -n 或 --name提供的名称。 如果用户未提供名称,引擎将使用当前目录名称。
preferNameDirectory boolean 否 当 true 和用户提供名称但不提供输出目录时,模板引擎会创建一个具有该名称的新目录,而不是将文件写入当前目录中。 默认值为 false。
tags 对象 否 标识模板语言和类型等属性的元数据。 用于tags.language语言和tags.type语言projectitem,或solution。

两个领域值得额外的关注。 字段 sourceName 是模板处理命名的方式:将其设置为文件名和源代码(如 MyTemplate)中显示的字符串,模板引擎会将每次匹配项替换为用户在创建模板时传递的任何名称。 字段 classifications 控制可发现性;选择准确描述模板用途的标记,以便用户可以在搜索时找到它。

下面是 template.json 控制台模板的最低要求:

{
  "$schema": "https://json.schemastore.org/template",
  "author": "Your Name",
  "classifications": [ "Common", "Console" ],
  "description": "Creates a console application.",
  "identity": "MyCompany.ConsoleTemplate.CSharp",
  "name": "My Console App",
  "shortName": "myconsole",
  "sourceName": "MyConsoleApp",
  "tags": {
    "language": "C#",
    "type": "project"
  }
}

完整的架构在 JSON 架构存储中可用。 有关高级配置选项,例如条件文件包含、创建后操作和多项目模板,请参阅 dotnet/templating GitHub wiki。

模板参数(符号)

该 symbols 部分 template.json 定义用户从模板创建时可以传递的参数。 每个符号都会成为 CLI dotnet new <shortName>选项,因此命名 ClassName 的符号将变为 --ClassName (或者 -C 定义短名称)。

每个符号条目都支持以下常见设置:

设置 Description
type 必须为 "parameter" 面向用户的参数。
description 用户运行时 dotnet new <shortName> -?在模板帮助输出中所示。
datatype 预期的数据类型,例如 "text", "bool"或 "choice"。
replaces 模板引擎将替换为参数值的源文件内容中的字符串。
fileRename 模板引擎将替换为参数值的源文件名称中的字符串。
defaultValue 用户未提供参数时使用的值。

符号 replaces 驱动替换的方式和 fileRename 设置。 当用户提供值时,模板引擎将替换文件内容内的字符串的每个匹配项 replaces 以及文件名中字符串的每个匹配项 fileRename 。 如果用户未提供值, defaultValue 则改用该值。

例如,以下符号允许用户在从模板创建时设置类名。 文件已重命名,其内的类将更新为匹配:

"symbols": {
  "ClassName": {
    "type": "parameter",
    "description": "The name of the code file and class.",
    "datatype": "text",
    "replaces": "StringExtensions",
    "fileRename": "StringExtensions",
    "defaultValue": "StringExtensions"
  }
}

定义此符号后,用户可以运行以生成包含名为 <a0/a0> 类的文件。 如果没有标志,文件和类将保留默认名称 StringExtensions。

若要验证模板公开的参数,请在安装模板后传递给 -? 其短名称:

dotnet new <shortName> -?

模板包

模板包是一个 NuGet (.nupkg) 文件,该文件将一个或多个模板捆绑在一起。 当用户安装模板包时,.NET模板引擎会一次注册其中的每个模板。 包是分发模板的标准方法。 将单个包发布到 NuGet.org 或专用 NuGet 源,或共享本地 .nupkg 文件,用户使用一个命令获取整个集合。

若要生成模板包,请使用配置为充当打包项目而不是编译项目的 C# 项目文件(.csproj)。 执行此操作的关键设置包括:

设置 价值 Purpose
PackageType Template 将包标记为模板包,使其显示在结果中 dotnet new search 。
IncludeContentInPack true 在 NuGet 包中包含内容文件。
IncludeBuildOutput false 防止编译的二进制文件添加到包。
ContentTargetFolders content 将模板文件夹置于 NuGet 包的文件夹 content 内,即模板引擎期望找到它们的位置。

项目 templatepack 模板提供了创建打包项目的最简单方法:

  1. 安装Microsoft。TemplateEngine.Authoring.Templates NuGet 包:

    dotnet new install Microsoft.TemplateEngine.Authoring.Templates
    
  2. 创建打包项目:

    dotnet new templatepack -n <PackageName>
    

生成的项目包括正确的 .csproj 设置、 content 模板的文件夹,以及模板验证和可选本地化的 MSBuild 任务。

有关创建、打包和发布模板包的完整演练,请参阅 教程:创建模板包。

在本地测试模板

在模板开发过程中,直接从其文件夹安装模板以测试模板,而无需先生成包。 将路径传递给包含该文件夹的 .template.config 目录:

dotnet new install ./mytemplate/

若要查看所有已安装的模板包和卸载每个包的确切命令, dotnet new uninstall 请运行,不带参数:

dotnet new uninstall

若要从目录中卸载安装的模板,请传递用于安装该模板的相同目录路径:

dotnet new uninstall ./mytemplate/

准备好共享模板后,将其打包为 NuGet 包(请参阅 模板包)并进行分发。 用户使用以下 dotnet new install 源参数之一安装已发布的模板:

  • NuGet 包 ID,它从为当前目录配置的 NuGet 源安装最新稳定版本:

    dotnet new install AdatumCorporation.ConsoleTemplate.CSharp
    
  • 具有自定义源 URL 的 NuGet 包 ID。 除了配置的 NuGet 源之外,该 --nuget-source 选项还对该安装使用指定的源:

    dotnet new install AdatumCorporation.ConsoleTemplate.CSharp --nuget-source https://mynugetfeed.example.com/v3/index.json
    
  • 本地 .nupkg 文件的路径:

    dotnet new install ./AdatumCorporation.ConsoleTemplate.CSharp.1.0.0.nupkg
    

Warning

模板可以在项目创建过程中运行 MSBuild 任务和任意代码。 仅从你信任的源安装模板。

若要从 NuGet 源或本地 .nupkg 文件卸载安装的包,请使用 NuGet 包 ID:

dotnet new uninstall AdatumCorporation.ConsoleTemplate.CSharp

内置 SDK 模板不会显示在卸载列表中,不能删除它 dotnet new uninstall。

模板本地化

.NET模板引擎支持模板元数据的可选本地化。 提供本地化文件时,主机(如 Visual Studio“新建Project”对话框)dotnet new会显示用户语言中模板的名称、说明和符号信息,而不是原始创作语言。

以下模板字段支持本地化:

  • name
  • author
  • description
  • 符号 description 和 displayName
  • 选项参数中每个选项的说明和显示名称
  • 发布操作 description 和 manualInstructions

若要添加本地化,请在其中.template.config创建一个localize子文件夹,并为每个语言添加一个 JSON 文件。 为每个文件 templatestrings.<lang-code>.json命名,其中 <lang-code> 匹配有效 CultureInfo 名称,例如 pt-BR, zh-Hans或 de。 每个文件都包含键值对,其中键是元素的路径 template.json,用作 / 嵌套字段的分隔符。

例如,给定 template.json 内容如下:

{
  "$schema": "https://json.schemastore.org/template",
  "author": "Microsoft",
  "classifications": [ "Config" ],
  "name": "EditorConfig file",
  "description": "Creates an .editorconfig file for configuring code style preferences.",
  "symbols": {
    "Empty": {
      "type": "parameter",
      "datatype": "bool",
      "defaultValue": "false",
      "displayName": "Empty",
      "description": "Creates empty .editorconfig instead of the defaults for .NET."
    }
  }
}

名为 templatestrings.pt-BR.json 巴西葡萄牙语的本地化文件如下所示:

{
  "author": "Microsoft",
  "name": "Arquivo EditorConfig",
  "description": "Cria um arquivo .editorconfig para configurar as preferências de estilo de código.",
  "symbols/Empty/displayName": "Vazio",
  "symbols/Empty/description": "Cria .editorconfig vazio em vez dos padrões para .NET."
}

模板引擎在加载模板信息时分析这些文件,并根据当前 UI 区域性自动返回本地化值,无需用户执行额外的步骤。

本地化是可选的。 如果未包含本地化文件,则模板正常工作,并且始终显示来自 template.json的值。 有关详细信息,请参阅 dotnet/templating wiki 本地化页面。

Visual Studio 集成

Visual Studio的“创建新项目”对话框使用.NET项目模板的.NET模板引擎。 你创作用于dotnet newVisual Studio的模板,无需任何额外的配置。 当用户使用 dotnet new install 安装模板包时,Visual Studio会自动检测并显示对话框中的这些模板。

Project和解决方案模板显示在“新建project”对话框中,以及内置 SDK 模板。 用户可以根据模板文件中的字段的名称、语言或标记 classifications 查找模板 template.json 。 准确的分类有助于模板在正确的筛选器类别中显示,因此请仔细选择它们。 若要在对话框中为模板提供美观的外观,请向.template.config文件夹添加一个 icon.png — Visual Studio模板名称旁边显示它。

项模板 当前不会显示在“ 添加新>项 ”对话框中。 用户仍然可以在终端中使用项模板和 dotnet new 命令。

若要使模板可供Visual Studio尚未安装模板的用户发现,请将模板包发布到 nuget.org。“创建新项目”对话框包括联机搜索选项中的“安装更多模板”选项,用于搜索模板包 nuget.org。 当用户通过该选项安装包时,Visual Studio使用相同的安装机制dotnet new install。

有关特定于Visual Studio集成(例如控制模板排序顺序和配置其他特定于 IDE 的选项)的更深入指南,请参阅 Sayed Hashimi 的模板示例存储库。