﻿# 自訂 dotnet new 專案範本的重要觀念與範例

.NET Core 內建的範本功能簡單好上手，由於架構簡化許多 (相較於 Visual Studio 範本)，所以也非常好上手。在仔細研究之後，發現還是蠻多小細節的，只要事先建立一些重要的基本觀念，要寫出好用、實用的專案範本一點都不麻煩。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/b624e6bf9faedeb94cac-72678313-9d560600-3adf-11ea-8935-9bbfff011ae5.jpg)

### 範本基本概念

-   列出目前所有範本
    
    透過 `-l` 參數可以列出目前所有已安裝的專案範本清單：
    
    ```bash
    dotnet new -l
    ```
    
    透過 `-u` 參數則會列出目前所有範本的詳細資訊：
    
    ```bash
    dotnet new -u
    ```
    
    > 雖然加上 `-u` 參數是用來移除現有範本之用，但是 `-u` 不加上參數時，卻可以列出目前所有範本的詳細資訊，你可以看見每個範本的 `NuGetPackageId` 與 `Version` 版本號，還能得知**移除範本**所需的命令！
    
-   範本的種類
    
    在 Visual Studio 裡面，範本有兩種：
    
    1.  專案範本 (Project Templates)
    2.  項目範本 (Item Templates)
    
    在使用 .NET Core CLI 的時候，你可以搭配 `--type` 參數來篩選範本，例如：
    
    ```bash
    dotnet new -l --type=project
    dotnet new -l --type=item
    dotnet new -l --type=other
    ```
    
    > 預設 `--type` 參數只有三種可能的值：`project`、`item` 與 `other`。
    

### 範本的組成項目

範本的組成包含兩種成分：

1.  來源檔案和資料夾
    
    也就是所有要被自動產生的**檔案**與**資料夾**，基本上不限定任何檔案型態或格式，任何檔案都可以當成範本的一部分。
    
2.  設定檔 (template.json)
    
    你必須建立一個 `.template.config/template.json` 設定檔，用來告訴 .NET Core CLI 該怎樣產生新檔案。其內容範例如下：
    
    ```json
    {
        "$schema": "http://json.schemastore.org/template",
        "identity": "Duotify.WebAPI.3.1",
        "author": "Will Huang",
        "classifications": [ "Common", "Code" ],
        "name": "Example templates: string extensions",
        "shortName": "duotify-webapi",
        "tags": {
            "language": "C#",
            "type": "project"
        },
        "sourceName": "MyProject.Con",
        "preferNameDirectory": true
    }
    ```
    
    上述這些 Properties (屬性) 除了 `tags` 以外，都是必要的屬性，分別說明如下：
    
    -   `$schema`: 此為 `template.json` 檔案的 JSON 結構描述 URI，只要設定上去，編輯器就會開始提供 IntelliSense 自動完成能力。
        
        ![image](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/50edd6f6ca6e29dd9724-72673878-e0e24d00-3aaa-11ea-9aa8-0967873634a9.png)
        
    -   `identity`: 此範本的**唯一名稱**，不能跟任何其他範本重複。
        
    -   `name`: 使用者在執行 `dotnet new -l` 時會看到的**範本名稱**。
        
    -   `shortName`: 執行 `dotnet new shortName` 命令時所使用的**範本短名**。
        
    -   `author`: 宣告範本的**作者名稱**。
        
    -   `classifications`: **範本分類** (字串陣列)。當你執行 `dotnet new -l` 列出範本清單時，會自動出現在「**標記**」(**Tags**) 欄位中。
        
    -   `tags`: 用來宣告範本的標記資訊，從名稱來看，很容易跟 `classifications` 混淆，因為都是「標記」的意思。這個屬性主要用來跟 `dotnet new` 的 `--type` 與 `-lang` 兩個參數搭配使用。`tags` 屬性下包含兩個子屬性：
        
        -   `language`: 程式語言。可能的值有：`C#`、`VB`、`F#`，除此之外你也可以設定為任何語言。
        -   `type`: 範本類型。這裡只有兩種可能的值：`project` (專案範本)、`item` (項目範本)。你也可以指定任意字串。
    -   `sourceName`: 指定**來源名稱**。
        
        -   我們在執行 `dotnet new` 的時候，可以指定 `-n` 參數，這個參數定義了**專案名稱**。
        -   這裡所定義的 `sourceName` 其實是一個可以被取代的變數，如果你設定為 `MyProject.Con` 的話，當你在執行 `dotnet new` 的時候，程式會自動找出**來源檔案和資料夾**中所有**檔案/目錄名稱**與**檔案內容**，並將 `MyProject.Con` 字串替換成 `-n` 參數指定的名稱字串。
    -   `preferNameDirectory`: 在執行 `dotnet new` 的時候，如果你有指定 `-n` 參數，預設會建立一個與 `-n` 參數值同名的資料夾，如果你將該屬性設定為 `false` 的話，就不會建立額外的資料夾。此屬性預設為 `true`。
        

### 群組識別與標記

如果你定義了 `groupIdentity` 屬性，會將多個範本合併成一個顯示項目，執行 `dotnet new` 的時候，就必須搭配 `--type` 或 `-lang` 參數來選擇要執行的範本。這個時候範本中的 `tags` 屬性就一定要設定了，該屬性下的 `language` 與 `type` 就是用來給這兩個參數篩選用的。

```bash
dotnet new mysample --type=item -lang=C#
dotnet new mysample --type=project -lang=C#
```

### 練習建立專案範本

請參考以下文件建立 **項目範本**、**專案範本** 與 **範本套件**！

1.  [教學課程：建立項目範本](https://learn.microsoft.com/zh-tw/dotnet/core/tutorials/cli-templates-create-item-template)
2.  [教學課程：建立專案範本](https://learn.microsoft.com/zh-tw/dotnet/core/tutorials/cli-templates-create-project-template)
3.  [教學課程：建立範本套件](https://learn.microsoft.com/zh-tw/dotnet/core/tutorials/cli-templates-create-template-pack)

如果想參考其他人所寫的範本，可以參考以下網址：

-   [.NET Template Samples](https://github.com/dotnet/dotnet-template-samples)
-   [ASP.NET Core 內建專案範本原始碼](https://github.com/dotnet/aspnetcore/tree/master/src/ProjectTemplates)
-   [示範各種不同 dotnet new 自訂範本的專案](https://github.com/doggy8088/netcore-templates-samples)
-   [Available templates for dotnet new](https://github.com/dotnet/templating/wiki/Available-templates-for-dotnet-new)

### 相關連結

-   Microsoft Docs
    -   [dotnet new 命令](https://learn.microsoft.com/zh-tw/dotnet/core/tools/dotnet-new)
    -   [dotnet new 的自訂範本](https://learn.microsoft.com/zh-tw/dotnet/core/tools/custom-templates)
    -   [template.json schema at the JSON Schema Store](http://json.schemastore.org/template)
-   [dotnet/templating GitHub repo Wiki](https://github.com/dotnet/templating/wiki)
    -   [Available Parameter Generators](https://github.com/dotnet/templating/wiki/Available-Parameter-Generators)
    -   [Post Action Registry](https://github.com/dotnet/templating/wiki/Post-Action-Registry)
    -   [Reference for template.json](https://github.com/dotnet/templating/wiki/Reference-for-template.json)
    -   [Blog posts](https://github.com/dotnet/templating/wiki/Blog-posts)
-   [Sayed Hashimi on Open Source .NET Core Project Templates - YouTube](https://www.youtube.com/watch?v=_hTkC02kaik)
