参考官方文档:

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

目录结构及建议

|--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,目录结构如下:

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
}

项目代码结构如下:

安装模板

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

dotnet new -i 模板源码路径

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

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

使用模板创建项目

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

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

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

文件夹结构如下:

代码结构如下:

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

创建动态模板

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

创建模板项目

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

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中表达式计算的结果,提供给模板作为判定数据库类型的。

项目代码结构如下:

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:\SourceCode\MyPractices\MyTestTemplates\templates\DynamicTplDemo\src

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

dotnet new DynamicTpl --help

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

使用模板创建项目

执行命令:

dotnet new DynamicTplDemoAPI -n MyDynamicApi -o E:\SourceCode\MyPractices\MyTestTemplates\codes\MyDynamicApi -S MSSQL

提示如下,则表示成功:

文件夹结构如下:

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

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.exe文件

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

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

创建.nuspec文件

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

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

文件内容如下:

<?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:\SourceCode\MyPractices\MyTestTemplates\tools\nuget.exe pack DynamicTplDemo.nuspec -OutputDirectory E:\SourceCode\MyPractices\MyTestTemplates\packages

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

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

发布包

想要在不同机器上方便使用包,是需要将包发布到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:\SourceCode\MyPractices\MyTestTemplates\packages\DynamicTplDemo.1.0.0.nupkg -src http://localhost:50557/v3/index.json

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

使用包

添加源

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

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

安装包

dotnet new --install DynamicTplDemo::1.0.0

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

使用包

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

dotnet new DynamicTplDemo -n MyDynamicTpl -o E:\SourceCode\MyPractices\MyTestTemplates\codes\MyDynamicTpl -S MSSQL

Nuget-自定义模板的创建与使用的更多相关文章

  1. 使用.Net Core CLI命令dotnet new创建自定义模板

    文章起源来自一篇博客:使用 .NET CORE 创建 项目模板,模板项目,Template - DeepThought - 博客园 之前使用Abp的时候就很认同Abp创建模板项目的方式.想不到.Net ...

  2. Django自定义模板

    定义simple_tag步骤 一.创建templatetags文件 首先在app下创建templatetags文件:名字不许叫这个,不能改变. 二.在文件中创建一个py文件 文件名自定义 三.在创建的 ...

  3. .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(三)

    阅读目录: 7.HtmlHelper.HtmlHelper<T>中的ViewModel的类型推断 8.控制ViewModel中的某个属性的呈现(使用PartialView部分视图细粒度控制 ...

  4. SharePoint 2013 自定义模板页后在列表里修改不了视图

    前言 最近系统从2010升级至2013,有自定义模板页.突然发现在列表中切换不了视图,让我很费解. 我尝试过以下解决方案: 去掉自定义css 去掉自定义js 禁用所有自定义功能 结果都没有效还是一样的 ...

  5. vim中如何引用自定义模板文件

    我们在使用vim新建文件时可以引用自定义模板,来避免重复的数据格式处理花费太多时间. 实现方法很简单,只需要2步即可:1. 在.vim/template目录放入自己的模板文件(如shellconfig ...

  6. RazorEngine在非MVC下的使用,以及使用自定义模板

    ---恢复内容开始--- RazorEngine模板引擎大大的帮助了我们简化字符串的拼接与方法的调用,开源之后,现在在简单的web程序,winform程序,甚至控制台程序都可以利用它来完成. 但如何在 ...

  7. xcode5 自定义模板

    经过一番周折,终于在xcode5上实现了一个简单的自定义模板,在项目中集成NSLogger库(增强NSLog的功能,https://github.com/fpillet/NSLogger)——新建项目 ...

  8. sharepoint 2010 使用自定义列表模版创建列表(2)

    前面用的方法是通过界面上操作,根据自定义模版,创建的列表.sharepoint 2010 使用自定义列表模版创建列表(1) 这里顺便记录多另一种方法,通过程序来创建. ---------------- ...

  9. 前端学PHP之自定义模板引擎

    前面的话 在大多数的项目组中,开发一个Web程序都会出现这样的流程:计划文档提交之后,前端工程师制作了网站的外观模型,然后把它交给后端工程师,它们使用后端代码实现程序逻辑,同时使用外观模型做成基本架构 ...

随机推荐

  1. Elasticsearch---DSL搜索实践

    Domain Specific Language 特定领域语言,基于JSON格式的数据查询,查询更灵活,有利于复杂查询 一.普通url路径参数搜索 数据准备 1.建立名字为 shop 的索引 2.手动 ...

  2. 二分图最小点覆盖构造方案+König定理证明

    前言 博主很笨 ,如有纰漏,欢迎在评论区指出讨论. 二分图的最大匹配使用 \(Dinic\) 算法进行实现,时间复杂度为 \(O(n\sqrt{e})\),其中, \(n\)为二分图中左部点的数量, ...

  3. 将项目加载到tomcat中的时候报错:Tomcat version 6.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 Web modules

    转自:http://jingwang0523.blog.163.com/blog/static/9090710320113294551497/ 最近在用eclipse做项目,新建项目时什么都贪新,用最 ...

  4. 后端程序员之路 32、Index搜索引擎实现分析1-类的设计

    # 1.forward_index 正排索引(正向索引)- filter_t- filter_judge # 2.inverted_index 倒排索引(反向索引)- inverted_pre_sco ...

  5. Mybatis系列全解(六):Mybatis最硬核的API你知道几个?

    封面:洛小汐 作者:潘潘 2020 年的大疫情,把世界撕成几片. 时至今日,依旧人心惶惶. 很庆幸,身处这安稳国, 兼得一份安稳工. · 东家常讲的一个词:深秋心态 . 大势时,不跟风.起哄, 萧条时 ...

  6. 通达OA 任意文件上传-2013/2015版本

    参考 http://wiki.0-sec.org/0day/%E9%80%9A%E8%BE%BEoa/11.html 影响版本 2013版本 2015版本 漏洞文件 general/vmeet/wbU ...

  7. CRLF注入漏洞 -配置错误

    漏洞分析参考 https://i-beta.cnblogs.com/posts/edit 什么是CRLF? CRLF 指的是回车符(CR,ASCII 13,\r,%0d) 和换行符(LF,ASCII ...

  8. Mark一个代码量统计工具-Statistic

    安装方式 IDEA.Goland系列插件市场搜索Statistic 简单说明 统计纬度比较丰富 基本覆盖常见纬度,如代码行数,文件大小等,各指标取最大最小及平均值. 统计目录为当前项目目录 只有在当前 ...

  9. C# 应用 - 使用 HttpListener 接受 Http 请求

    1. 库类: \Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\System.dll System.Net.HttpListen ...

  10. C#开发BIMFACE系列37 网页集成开发1:审图系统中加载模型或图纸

    系列目录     [已更新最新开发文章,点击查看详细] 在之前的<C#开发BIMFACE系列>中主要介绍了BIMFACE平台提供的服务端API接口的封装开发与测试过程. 服务端API测试通 ...