Nuget-自定义模板的创建与使用

  • A+
所属分类:.NET技术
摘要

https://docs.microsoft.com/zh-cn/dotnet/core/tools/custom-templateshttps://devblogs.microsoft.com/dotnet/how-to-create-your-own-templates-for-dotnet-new/

参考官方文档:

https://docs.microsoft.com/zh-cn/dotnet/core/tools/custom-templates

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

为什么要自定义模板?

通常情况下,项目都是由多个子项目组成,相互之间有一定的依赖关系,每个子项目又有各自依赖的包,也有必需的配置项、公共代码等。当每次创建一个相同结构的项目时,需要手动创建这些子项,手动加入依赖,复制配置项和公共代码等,这是一个没有技术含量、繁琐且容易出错的操作。虽然可以通过建立模板代码库达到以上效果,但是拉取代码库后需要修改项目名称,剔除不需要的依赖包等,也很繁琐。dotnet new命令提供了自定义模板能力,可以根据自己的需要,动态创建项目。

template.json介绍

该文件是创建模板必须的,它包含了创建模板所需的配置信息,下面是必须的配置项。

关于它的完整定义可参考英文文档:https://github.com/dotnet/templating/wiki/Reference-for-template.json

Nuget-自定义模板的创建与使用

目录结构及建议

 

|--templates    |--mytemplate    |  |--src    |     |--.template.config    |     |  |--template.json    |     |--模板源代码    |--mytemplate01       |--src          |--.template.config          |  |--template.json          |--模板源代码 

 

说明:

templates:可以把多个模板都放在该文件夹下,便于管理。

mytemplate:该文件夹为所需要创建的模板。如果需要多个模板,只需在其同级建立其他模板文件夹,例如mytemplate01。

src:模板源代码存放文件夹。

.template.config/template.json:模板配置信息。

模板源代码:存放自定义的模板源代码。

创建简单模板并使用

现在来创建一个简单的模板,并进行模板的安装和根据模板创建项目。这个模板为三层结构的WebApi项目,平台版本为.Net5,添加Sqlserver驱动包和Dapper包,接口文档使用Swagger,并逐层注入容器。

创建模板项目

新建一个模板项目,命名SingleTplDemo,目录结构如下:

Nuget-自定义模板的创建与使用

template.json文件内容如下:

 

{     "$schema": "http://json.schemastore.org/template",     "author": "Bai Li",      "classifications": [ "Web/WebAPI" ],      "name": "SingleTplDemoAPI",      "identity": "SingleTplDemoAPI",      "shortName": "SingleTpl",      "tags": {       "language": "C#" ,       "type":"project"     },     "sourceName": "SingleTplDemo",       "preferNameDirectory": true } 

 

项目代码结构如下:

Nuget-自定义模板的创建与使用

安装模板

使用dotnet new -i命令安装本地模板(后面会介绍安装远程模板),格式如下:

 

dotnet new -i 模板源码路径 

 

模板源码路径为.template.config文件夹所在的路径。

模板安装完成后,执行dotnet new命令,可以在已安装模板列表中看到

Nuget-自定义模板的创建与使用

使用模板创建项目

使用dotnet new命令根据指定模板创建项目,格式如下:

 

dotnet new 模板名称 -n 项目名称 -o 目标路径 

 

Nuget-自定义模板的创建与使用

提示成功,则项目创建成功。

文件夹结构如下:

Nuget-自定义模板的创建与使用

代码结构如下:

Nuget-自定义模板的创建与使用

可以看到通过这个模板创建的项目,结构和代码文件一致。

创建动态模板

现在也创建一个三层结构的WebAPI,平台版本为.Net5,ORM使用Dapper,接口文档使用Swagger,并逐层注入容器。跟简单模板不同的是,数据驱动包含SqlServer和MySQL。接下来的计划是,在通过模板创建项目时,仅使用引入一种数据驱动。

创建模板项目

新建项目模板,结构目录结构如下:

Nuget-自定义模板的创建与使用

template.json文件内容如下:

 

{     "$schema": "http://json.schemastore.org/template",     "author": "Bai Li",      "classifications": [ "Web/WebAPI" ],      "name": "DynamicTplDemo",      "identity": "DynamicTplDemo",      "shortName": "DynamicTpl",      "tags": {       "language": "C#" ,       "type":"project"     },     "sourceName": "DynamicTplDemo",       "preferNameDirectory": true, 	"symbols": { 	  "SqlType": { 		"type": "parameter", 		"description": "Sql类型", 		"dataType": "choice", 		"defaultValue": "MSSQL", 		"isRequired": true, 		"choices": [ 		  { 			"choice": "MSSQL", 			"description": "MS SQL" 		  }, 		  { 			"choice": "MySQL", 			"description": "My SQL" 		  } 		] 	  }, 	  "MSSQL": { 		"type": "computed", 		"value": "(SqlType == "MSSQL")" 	  }, 	  "MySQL": { 		"type": "computed", 		"value": "(SqlType == "MySQL")" 	  } 	} } 

 

该文件引入了新的配置:symbols

参考文档:https://github.com/dotnet/templating/wiki/Reference-for-template.json#symbols

symbols配置项内的有五种类型的子项,这里仅介绍用到的两种类型,其余的请参考官方文档:

SqlType:作为模板的参数,在创建项目时,需要指定可选值choice。

MSSQL、MySQL:通过value中表达式计算的结果,提供给模板作为判定数据库类型的。

项目代码结构如下:

Nuget-自定义模板的创建与使用

DbContext.cs文件中,通过预编译指令#if等,实现MSSQL和MySQL驱动,以及对应IDbConnection实现的切换。完整内容如下:

 

using System.Data; #if MSSQL using Microsoft.Data.SqlClient;  #elif MySQL using MySql.Data.MySqlClient; #endif  namespace DynamicTplDemo.Infrastructure {     /// <summary>     /// 数据库上下文     /// </summary>     public class DbContext     {         /// <summary>         /// 连接字符串         /// </summary>         private string _connStr;         public DbContext(string connStr)         {             _connStr = connStr;         }         /// <summary>         /// 打开连接         /// </summary>         /// <returns></returns>         public IDbConnection OpenConnection()         {             IDbConnection conn = null; #if MSSQL             conn = new SqlConnection();  #elif MySQL             conn = new MySqlConnection(); #endif             conn.ConnectionString = _connStr;             conn.Open();             return conn;         }     } } 

 

DynamicTplDemo.Infrastructure.csproj文件中,通过节点PackageReference的Condition属性的表达式切换。完整内容如下:

 

<Project Sdk="Microsoft.NET.Sdk">   <PropertyGroup>     <TargetFramework>net5.0</TargetFramework>   </PropertyGroup>   <ItemGroup>     <PackageReference Include="Microsoft.Data.SqlClient" Version="3.0.0-preview1.21075.2" Condition="'$(MSSQL)'=='true'" />     <PackageReference Include="MySql.Data" Version="8.0.23" Condition="'$(MySql)'=='true'" />   </ItemGroup> </Project> 

 

安装模板

安装命令:

 

dotnet new -i E:SourceCodeMyPracticesMyTestTemplatestemplatesDynamicTplDemosrc 

 

查看该模板信息,执行命令:

 

dotnet new DynamicTpl --help 

 

可以看到,该模板增加了选项-S|--SqlType,且该选项的可选值有MSSQL和MySQL。

Nuget-自定义模板的创建与使用

使用模板创建项目

执行命令:

 

dotnet new DynamicTplDemoAPI -n MyDynamicApi -o E:SourceCodeMyPracticesMyTestTemplatescodesMyDynamicApi -S MSSQL 

 

提示如下,则表示成功:

Nuget-自定义模板的创建与使用

文件夹结构如下:

Nuget-自定义模板的创建与使用

代码结构如下,可以看到自动引入了MSSQL的驱动包:

Nuget-自定义模板的创建与使用

DbContext.cs文件中,也可以看到仅包含了MSSQL的引用,以及SqlConnection类:

 

using System.Data; using Microsoft.Data.SqlClient;   namespace MyDynamicApi.Infrastructure {     /// <summary>     /// 数据库上下文     /// </summary>     public class DbContext     {         /// <summary>         /// 连接字符串         /// </summary>         private string _connStr;         public DbContext(string connStr)         {             _connStr = connStr;         }         /// <summary>         /// 打开连接         /// </summary>         /// <returns></returns>         public IDbConnection OpenConnection()         {             IDbConnection conn = null;             conn = new SqlConnection();              conn.ConnectionString = _connStr;             conn.Open();             return conn;         }     } } 

 

模板打包成Nuget包,并上传Nuget服务器

以上便是创建和使用模板的方法,但是直接将文件夹安装为模板,不是一个好的用法。因为在实际工作中,其他机器上需要使用该模板,就要把文件夹复制过去安装,很不方便。那这里就分享一下将模板打包称Nuget包,并上传到Nuget服务器,其他机器只需要执行两行命令,就可以轻松使用上模板。

模板打包

创建文件夹

建议在templates文件夹的同级新建文件夹:packages、tools。

tools:存放工具软件,下面内容会讲到。

packages:存放生成的包,下面内容会讲到

Nuget-自定义模板的创建与使用

下载nuget.exe文件

下载路径:https://www.nuget.org/downloads

选择合适的版本,下载到上面新建的tools文件夹下。

Nuget-自定义模板的创建与使用

创建.nuspec文件

参考文档:https://docs.microsoft.com/zh-cn/nuget/create-packages/creating-a-package

在模板项目的根目录下创建.nuspec文件,本部分内容在上面创建的动态模板上进行,故选择命名:DynamicTplDemo.nuspec。

Nuget-自定义模板的创建与使用

文件内容如下:

 

<?xml version="1.0" encoding="utf-8"?> <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">   <metadata>     <id>DynamicTplDemo</id> 	<version>1.0.0</version> 	<authors>Bai Li</authors> 	<description>动态模板包</description> 	<copyright>Copyright ©2021 Contoso Corporation</copyright> 	<packageTypes>       <packageType name="Template" />     </packageTypes>   </metadata>   <files> 	<file src="src**" target="src" exclude="**bin**;**obj**" />   </files> </package> 

 

官方文档中关于节点的说明定义很清晰,可前往查阅。需要注意的是files>file节点,这里用来排除模板中各子项目下的bin和obj文件夹。

打包模板,并生成.nupkg文件

上面准备工作完成,开始进行打包。这里通过tools文件夹下的nuget.exe工具,将指定的模板项目打包称.nupkg文件,并输出到上面定义好的packages文件夹下。

切换到指定的项目文件夹下,执行如下命令:

 

E:SourceCodeMyPracticesMyTestTemplatestoolsnuget.exe pack DynamicTplDemo.nuspec -OutputDirectory E:SourceCodeMyPracticesMyTestTemplatespackages 

 

当提示如下内容,则表示生成包成功。

Nuget-自定义模板的创建与使用

在packages文件夹下,可以看到已生成包:

Nuget-自定义模板的创建与使用

发布包

想要在不同机器上方便使用包,是需要将包发布到nuget包服务器上,通常有两种方式:Nuget.org、私有源。

发布到Nuget.org

参考文档:https://docs.microsoft.com/zh-cn/nuget/nuget-org/publish-a-package

发布到私有源

参考文档:https://docs.microsoft.com/zh-cn/nuget/hosting-packages/overview

私有源有Azure、Nuget.Server、开源项目。

这里使用Baget开源项目(https://github.com/loic-sharma/BaGet),通过Docker部署,直接使用公共镜像:

 

#拉取镜像 docker pull loicsharma/baget #运行容器 docker run --rm --name nuget-server -p 50557:80 loicsharma/baget:latest 

 

注:此处使用公共镜像部署仅为了简单展示包的上传和安装步骤。

Baget部署后,使用nuget.exe上传包:

参考文档:https://docs.microsoft.com/zh-cn/nuget/reference/cli-reference/cli-ref-push

 

nuget.exe push E:SourceCodeMyPracticesMyTestTemplatespackagesDynamicTplDemo.1.0.0.nupkg -src http://localhost:50557/v3/index.json 

 

上传成功后,可以在Baget服务器上看到上传的包。

Nuget-自定义模板的创建与使用

使用包

添加源

将上面自建的Nuget源添加到Nuget配置中,以便后面使用,添加源命令:

 

dotnet nuget add source http://localhost:50557/v3/index.json -n MyBaget 

 

安装包

 

dotnet new --install DynamicTplDemo::1.0.0 

 

安装成功后,可以看到该包:

Nuget-自定义模板的创建与使用

使用包

包的使用,跟上面“创建动态模板”的“使用模板创建项目”方式一致:

 

dotnet new DynamicTplDemo -n MyDynamicTpl -o E:SourceCodeMyPracticesMyTestTemplatescodesMyDynamicTpl -S MSSQL