场景:日常工作中,你可能会碰到需要新建一个全新的解决方案的情况(如公司新起了一个新项目,需要有全新配套的后台程序),如果公司内部基础框架较多、解决方案需要DDD模式等,那么从新起项目到各种依赖引用到能实际可用,一大堆的配置都需要重新设定、测试,耗时耗力,根据项目的大小,往往可能需要
1-2 小时甚至更久。

在 .net core 之前,虽然有相关的解决方法可以实现“项目模板”这个需求,但在具体操作时很不方便,从 .net core 1.0
开始,提供了“模板引擎”,增加了 dotnet new --install(-i) 命令和选项,通过该命令,可以让你方便的创建属于你自己的项目模板。

通过本文你可以了解和掌握:

* 掌握如何将一个现有解决方案中的项目作为项目模板。
* 掌握如何在本地创建项目模板并安装和使用。
* 掌握如何将本地模板打包成 nuget 包,并通过包 id 进行安装使用该模板。
* 了解、掌握简单的 dotnet 和 nuget 命令及其配置。(windows 和 mac 会做差异说明)
准备工作

本次项目结构如下(DDD):

你可以在我的 github 库:
https://github.com/ArtechChu/Template <https://github.com/ArtechChu/Template>
直接下载该模板源码



* 用于发布的项目一共两个,Template.Console 和 Template.WebApi
* 其中 Console 项目就是简单的引用了下其他项目进行输出。
* WebApi 项目简单配置了下依赖注入,你可以将此项目作为 api 模板项目来说
Console 项目概要:



WebApi 项目概要:



将本地项目作为本地模板,通过命令进行安装和使用

*
本次示例以 Console 为例,将控制台项目涉及到的项目拷贝一份到如下文件夹中:



*
手动创建一个名为“.template.config”的文件夹,并在该文件夹内创建文件:template.json
{ "$schema": "http://json.schemastore.org/template", "author": "Artech",
"classifications": [ "Console" ], "name": "Custom Console", "identity": "Custom
Console", //模板唯一标识 "groupIdentity": "Custom Console", "shortName":
"CustomConsole", //【修改】短名称,使用 dotnet new <shortName> 安装模板时的名称 "tags": {
"language": "C#", "type": "project" }, "sourceName": "Template", //【修改】在使用 -n
选项时,会替换模板中项目的名字 "preferNameDirectory": true }
* 这里主要说明下 shortName 和 sourceName 这 2 个属性。
* shortName:短名称,用于在使用“dotnet new -l”命令时显示,安装时也可直接根据该短名称进行安装。
* sourceName:当我们在使用"dotnet new" 命令进行安装时,如果指定了 -n 或者 -o 选项,那么选项后面的名字会自动替换
sourceName 中指定的名字,因为我们的项目命名规则是
"Template.XXXX",所以这里设定为“Template”,如果你的项目命名规则是“公司.项目.XXX”,那么这里请设定为“公司.项目”。
*
安装该模板到本地模板库
# 通过如下命令查看当前本机已安装模板: dotnet new -l

# 模板安装命令:dotnet new i <path | nugetId> # 这里因为是安装本地模板,直接使用路径(绝对和相对均可) dotnet
new -i .


*
安装该短名称为 CustomConsole 的模板

假定安装路径为 D:\TestTemplate
假定新起的项目名为“Company.Group”
# 这里使用 -n 和 -o 选项来分别指定新项目的名字以及输出目录 # 设定新项目的名字为“Company.Group”,因为当前定位已经在
TestTemplate 文件夹内,所以直接用“.”,如下: dotnet new CustomConsole -n Company.Group -o .


文件夹内容如下:

* 使用模板新建的项目文件夹自动为“Company.Group.XXXX”
测试:



更多关于 template.json 的说明请参考:http://json.schemastore.org/template
<http://json.schemastore.org/template>

* 在 template.json 中,你还可以指定 symbols 等,来实现更多的自定义功能,如联动预编译指令等等。
将本地项目打包为 nuget 包,并通过命令进行安装和使用

本次示例以 Console +WebApi 为例,在 Templates\Nuget 文件夹中,建立 Content 文件夹用于存放 nuget
包内容,具体如下:



* ConsoleTemplate 中的 .template.config\template.json 内容同上方 Console 示例。
*
WebApiTemplate 中的 .template.config\template.json 内容如下:
{ "$schema": "http://json.schemastore.org/template", "author": "Artech",
"classifications": [ "WebApi" ], "name": "Custom WebApi", "identity": "Custom
WebApi", "groupIdentity": "Custom WebApi", "shortName": "CustomWebApi", "tags":
{ "language": "C#", "type": "project" }, "sourceName": "Template",
"preferNameDirectory": true }
*
在 content 目录内创建一个 nuspec 文件:Custom.Template.NetCore.nuspec,内容如下:
<?xml version="1.0" encoding="utf-8"?> <package
xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd"> <metadata>
<id>Custom.Template.NetCore</id> <version>1.0.1</version> <description> Custom
Template, including WebApi, Console </description> <authors>Artech</authors>
<packageTypes> <packageType name="Template" /> </packageTypes> </metadata>
</package>
* 需要注意,packageType 为 Template,metadata.id 必须保证唯一,其他按需设置即可。
* 必须是在 content 文件夹内。nuget 在打包的时候,是根据 content 文件夹来进行的。
*
使用 nuget pack 命令打包
# 注意路径的相对位置 nuget pack Custom.Template.NetCore.nuspec -OutputDirectory .


*
打包后的内容为:



*
发布该 nuget 包到 nuget server

这里用的是自建 nuget server,你可以按自身情况打包上传。



* 你可以直接使用 Nuget Package Explorer 进行发布包
* 也可以使用 nuget push 来发布,如下: nuget push Custom.Template.NetCore.1.0.1.nupkg
-Source "你的nuget 服务 url" -ApiKey "你的nuget api key"
*
通过 nuget 安装模板到本地

*
安装前本地已经安装的模板如下:


*
安装
dotnet new -i Custom.Template.NetCore::*


*
通过模板安装 CustomWebApi

安装路径为:D:\TestWebApiTemplate
dotnet new CustomWebApi -n Company.Group -o .
*
创建一个解决方案,并将所有的项目添加到解决方案 Company.Group.sln 中
dotnet new sln -n Company.Group # windows 下无法使用 glob pattern 只能逐个添加 dotnet sln
Company.Group.sln add
Company.Group.Application\Company.Group.Application.csproj dotnet sln
Company.Group.sln add Company.Group.Domain\Company.Group.Domain.csproj dotnet
sln Company.Group.sln add
Company.Group.DomainService\Company.Group.DomainService.csproj dotnet sln
Company.Group.sln add
Company.Group.IApplication\Company.Group.IApplication.csproj dotnet sln
Company.Group.sln add
Company.Group.IDomainService\Company.Group.IDomainService.csproj dotnet sln
Company.Group.sln add
Company.Group.Infrastructure.CrossCutting\Company.Group.Infrastructure.CrossCutting.csproj
dotnet sln Company.Group.sln add
Company.Group.Repository\Company.Group.Repository.csproj dotnet sln
Company.Group.sln add Company.Group.WebApi\Company.Group.WebApi.csproj


如果你用的是 mac / linux ,则可以直接用 globbing pattern 来添加,如下:
dotnet sln Company.Group.sln add **/*.csproj


参考


https://devblogs.microsoft.com/dotnet/how-to-create-your-own-templates-for-dotnet-new/

<https://devblogs.microsoft.com/dotnet/how-to-create-your-own-templates-for-dotnet-new/>

https://github.com/dotnet/dotnet-template-samples
<https://github.com/dotnet/dotnet-template-samples>

https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new?tabs=netcore22
<https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new?tabs=netcore22>

https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools
<https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools>