Nuget-自定義模板的創建與使用


參考官方文檔:

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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM