自定义c#项目模板的核心在于创建一个包含预设结构、文件和配置的源项目,并通过template.json文件定义模板行为。步骤包括:1.准备源项目,包含所需文件结构、nuget包引用等;2.创建.template.config文件夹;3.编写template.json定义模板元数据、占位符和参数;4.配置sourcename用于替换项目名称;5.使用dotnet new -i命令安装模板;6.通过dotnet new命令生成新项目。template.json的关键配置项包括author、name、shortname、sourcename、symbols和postactions,可支持用户输入参数和生成后操作。从现有项目创建模板时需清理临时文件,并确保占位符正确替换。安装后可通过测试生成新项目验证模板效果,必要时调试并迭代优化。

自定义C#项目模板,核心在于创建一个包含你预设结构、文件和配置的“源项目”,然后通过一个特殊的
template.json文件告诉
dotnet new命令如何将这个源项目转换成可复用的模板。这其实就是把一套你常用的项目初始化步骤固化下来,变成一个可以一键生成的“脚手架”。
解决方案
要自定义C#项目模板,你需要:
-
准备一个源项目: 这是一个普通的C#项目,包含了你希望模板生成的全部内容,比如特定的文件结构、默认的代码、NuGet包引用、
.editorconfig文件、甚至CI/CD的配置文件等等。 创建
.template.config文件夹: 在你的源项目的根目录下,创建一个名为
.template.config的隐藏文件夹。 编写
template.json文件: 在
.template.config文件夹内,创建一个
template.json文件。这个文件是模板的核心,它定义了模板的名称、短名称(用于
dotnet new命令)、作者、标签,以及最重要的——如何处理源项目中的文件和如何接受用户的输入参数。 配置占位符: 在源项目的文件中,将那些会随着新项目创建而变化的部分(比如项目名称、命名空间等)替换成
template.json中定义的占位符(通常是
sourceName)。 安装模板: 使用
dotnet new -i命令来安装你的自定义模板。这个路径可以是包含
.template.config的本地文件夹,也可以是一个NuGet包。 使用模板: 安装后,你就可以像使用内置模板一样,通过
dotnet new -n来创建新项目了。
为什么需要自定义C#项目模板?
说实话,我个人觉得自定义C#项目模板简直是项目启动阶段的“效率神器”。我们都知道,一个新项目开始时,总有那么一套固定的流程:创建项目、添加几个常用的NuGet包(比如日志、DI容器)、配置
appsettings.json、可能还要加个
README.md或者
.editorconfig。这些事儿虽然不复杂,但每次都手动来一遍,日积月累下来那时间成本和心智负担可不小。
更重要的是,它能确保团队内部的项目风格和技术栈保持一致。想象一下,如果每个开发者都按自己的习惯来初始化项目,那后续的代码审查、维护和新成员的上手成本都会显著增加。一个好的自定义模板,能把团队的最佳实践、预设的架构模式、甚至是一些强制性的编码规范(比如通过预置
Directory.Build.props)直接固化到项目骨架里。这样一来,新项目从一开始就站在了“巨人”的肩膀上,减少了犯错的可能,也让大家能更快地进入核心业务逻辑的开发。对我来说,这不仅是节省时间,更是提升团队协作效率和项目质量的关键一步。
自定义模板的核心:template.json配置详解
template.json是自定义模板的“灵魂”,它告诉
dotnet new命令你的模板是什么,能做什么。理解它的关键配置项,你就能玩转模板。
$schema: 通常指向一个JSON Schema定义,帮助IDE提供智能提示和验证。
author: 模板作者的名称。
classifications: 标签,用于
dotnet new -l列出模板时进行分类,比如
Web、
Console、
Library。
identity: 模板的唯一标识符。
name: 模板的显示名称,会出现在
dotnet new -l的列表中。
shortName: 模板的短名称,这是你实际使用
dotnet new命令时输入的名称,比如
dotnet new mywebapi。
tags: 键值对,用于描述模板类型和语言,例如
"language": "C#"。
sourceName: 这是非常关键的一个配置项。它定义了一个字符串,这个字符串会作为“占位符”出现在你的源项目文件(如
.csproj文件、
.cs文件中的命名空间)中。当用户通过模板创建新项目时,
dotnet new会自动把这个
sourceName字符串替换成用户指定的新项目名称。比如,如果你的
sourceName是
"MyTemplateProject",那么你源项目里所有
MyTemplateProject的地方都会被替换成用户输入的项目名。
symbols: 这里定义了用户可以通过命令行参数传递给模板的变量。每个
symbol可以有:
type:
parameter(用户输入)、
bool(布尔值)、
choice(多选一)。
description: 参数的描述。
defaultValue: 默认值。
replaces: 如果是
parameter类型,可以指定一个字符串,模板引擎会用用户输入的值替换源项目文件中的这个字符串。
choices: 如果是
choice类型,定义可选项。
postActions: 定义模板生成后要执行的操作,比如
restore(恢复NuGet包)、
open-in-vs(在Visual Studio中打开)。
一个简单的
template.json示例可能长这样:
{
"$schema": "http://json.schemastore.org/template",
"author": "你的名字",
"classifications": [ "Common", "Console" ],
"identity": "MyCompany.ConsoleTemplate",
"name": "My Company Console Application",
"shortName": "myconsole",
"tags": {
"language": "C#",
"type": "project"
},
"sourceName": "MyTemplateProject",
"symbols": {
"Framework": {
"type": "parameter",
"description": "The target framework for the project.",
"datatype": "string",
"defaultValue": "net8.0",
"replaces": "net8.0"
},
"UseLogging": {
"type": "bool",
"description": "Include Serilog logging setup.",
"defaultValue": "true"
}
},
"postActions": [
{
"description": "Restore NuGet packages.",
"manualInstructions": [],
"actionId": "210D431B-A78B-4D2F-B762-4ED3E92DFF25",
"args": {
"restore": ""
},
"continueOnError": true
}
]
}实际操作:从一个现有项目创建自定义模板的步骤
从一个现有项目创建自定义模板,就像是把你精心打造的“样板房”打包起来,让别人可以直接拎包入住。
准备你的“样板房”项目:
首先,创建一个普通的C#项目,或者选择一个你已经有的、想要作为模板基础的项目。 在这个项目里,添加所有你希望新项目默认包含的内容:比如特定的NuGet包(Microsoft.Extensions.Logging、
Newtonsoft.Json)、常用的代码文件(
Program.cs的特定初始化逻辑、
Startup.cs的DI配置)、
.editorconfig、
Directory.Build.props等等。 清理不必要的文件: 删除
bin、
obj文件夹,
.vs文件夹,
*.user文件,以及任何其他构建或IDE生成的临时文件。这些不应该包含在模板里。
创建.template.config
目录:
.csproj文件同级),创建一个名为
.template.config的文件夹。注意,这个文件夹通常是隐藏的。
编写template.json
文件:
.template.config文件夹内,创建
template.json。 配置基础信息: 填写
name、
shortName、
author、
classifications、
tags。 设置
sourceName: 这一步很关键。你需要确定一个“占位符”字符串,这个字符串在你的源项目文件(如
.csproj、
.cs中的命名空间)中是唯一的,并且你希望它被新项目的名称替换。例如,如果你的源项目叫
MyAwesomeProjectTemplate,那么你可以设置
"sourceName": "MyAwesomeProjectTemplate"。 定义
symbols(可选但推荐): 如果你希望用户在创建项目时能通过命令行参数控制某些行为(比如选择不同的.NET版本、是否包含某个功能模块),就在
symbols里定义它们。
替换源项目中的占位符:
打开你的源项目文件(.csproj、
.cs、甚至一些配置文件)。 把你之前在
template.json中定义的
sourceName字符串,替换掉所有需要根据新项目名称而变化的地方。 例如,如果你的
sourceName是
"MyAwesomeProjectTemplate",那么在
MyAwesomeProjectTemplate.csproj中,
<rootnamespace>MyAwesomeProjectTemplate</rootnamespace>会保持原样,因为
dotnet new会自动替换它。同样,在
Program.cs中
namespace MyAwesomeProjectTemplate也会被替换。 如果你定义了
symbols,并且使用了
replaces属性,那么也要确保源项目中有对应的字符串会被替换。
测试和安装模板:
本地安装: 在你的“样板房”项目根目录(也就是.csproj文件和
.template.config文件夹所在的目录)下,打开命令行,运行
dotnet new -i ./。这会将当前目录作为模板源进行安装。 测试使用: 切换到一个完全不同的空目录,然后运行
dotnet new -n MyNewProject。检查生成的新项目是否符合预期。 调试技巧: 如果模板没有按预期工作,可以使用
dotnet new -n MyNewProject --debug:all来获取更详细的调试信息。
卸载模板(可选):
当你完成测试或不再需要这个本地模板时,可以通过dotnet new -u或
dotnet new -u来卸载它。
记住,自定义模板是一个迭代的过程。你可能需要多次修改
template.json和源项目文件,然后重新安装和测试,直到它完美符合你的需求。这就像在雕刻一件作品,需要耐心和细致。
