跳至主要內容

ASP.NET Core 6 專案範本

Pamis Wang大约 8 分鐘後端ASP.NET CoreASP.NET Core 6

ASP.NETopen in new window Core 6 專案範本

前言

當開發同類型的專案一段時間都會有一些固定的設計模式,
或是一些常開發的功能:身分驗證、資料修改、郵件發送、報表產出。

然而每次開發專案都要從舊專案複製過來刪改,
或是另開新的專案範本重新建立資料夾和各類程式片段,
無形之中浪費許多人的時間,
對於多人協作專案沒有可依循的規範容易造成許多歧見。

職業倦怠就是這回事
職業倦怠就是這回事

本次目標為建立一個 Web API 專案範本,然後丟到 Nuget 上。

動機

之所以會想要搞個 ASP.NET Core 專案範本,
其動機由來是因為接觸了 Laravel 框架。

體驗到一個專注以網頁開發為主的框架對於開發體驗的幫助。

網頁開發會碰到的需求幾乎都有支援的套件可以快速實作,
官方也有詳細的官方文件讓多人團隊有規範可以依循,
進而提升團隊整體的軟體品質與降低後續接手維護的成本。

範本類型

ASP.NET Core 有兩種專案範本

  • 專案範本
  • 項目範本

本次教學以專案範本為例。

專案範本

Visual Studio 建立新專案會看到的就是專案範本

項目範本

Visual Studio 在專案內新建項目的就是項目範本

專案範本

建立專案範本

建立一個 Web API 專案範本。

修改專案範本

加入自己要的東西或是做一些修改。

例如本次範例我們建立一個 ViewModels 資料夾,
並且把 WeatherForecast.cs 放進去。

建立範本設定

範本資料夾中的所有檔案和資料夾都會包含為範本的一部分,除了特殊設定資料夾之外。
預設會被忽略的檔案和資料夾可見 範本設定參考open in new window

在專案資料夾內新增範本設定檔 .template.config/template.json
可參考官方的範例或是下方範例

{
  "$schema": "http://json.schemastore.org/template",
  "author": "Pamis Wang",
  "classifications": ["Web", "WebAPI"],
  "identity": "Pamis ASP.NET Core 6 Web API",
  "name": "Pamis ASP.NET Core 6 Web API",
  "shortName": "pamis-webapi",
  "sourceName": "WebAPI",
  "tags": {
    "language": "C#",
    "type": "project"
  },
  "preferNameDirectory": true,
  "sources": [
    {
      "modifiers": [
        {
          "exclude": [
            "**/[Bb]in/**",
            "**/[Oo]bj/**",
            ".template.config/**/*",
            "**/*.filelist",
            "**/*.user",
            "**/*.lock.json",
            "**/.vs/**",
            "**/.vscode/**",
            "**/.git/**/*"
          ]
        }
      ]
    }
  ]
}

範本設定說明

這下表格為必須使用的設定

成員類型描述
$schemaURItemplate.json 檔案的 JSON 結構描述。 VSC 需要此成員才能啟用 IntelliSense。
authorstring範本的作者。
classificationsarray(string)範本的分類。出現在使用 dotnet new list 命令時
identitystring此範本的唯一名稱。
namestring使用者應該會看到的範本名稱。
shortNamestring此範本名稱是由使用者指定,以 dotnet CLI 命令可輸入簡短名稱。
sourceNamestring要取代的專案名稱,詳細說明看下方補充

以下則為其他可用的設定

成員類型描述
preferNameDirectorystring指出是否要在指定名稱但未設定輸出目錄時,為範本建立目錄。預設值為 false。
tagsobject物件屬性有 languagetype
languagestringlanguage是程式語言,通常為 C#VB F#
typeenumtype 是範本類型,project (專案範本)、item(項目範本)、solution(解決方案)
excludearray(string)要排除的資料夾和檔案

當建立範本用 dotnet new <範本名稱> -n <專案名稱>
會將 sourceName 的字串替換成 -n 指定的專案名稱,
一般來說就是打範本的專案名稱。

當建立範本用 dotnet new <範本名稱> -n <專案名稱>
preferNameDirectory 會影響專案建立的資料夾設定
預設是 false(很多教學可能因為版本差異都寫成true

  • true:在目前指向的目錄建立一個與專案名稱相同的資料夾與專案內容。

  • false:在目前指向的目錄建立專案內容,「不會」建立與專案名稱相同的資料夾。

exclude 預設只會排除以下規則的檔案與資料夾:
binobj.template.config.filelist.user.lock.json

考慮到專案可能會加入版控,
以及用 IDE 開專案會冒出一堆鬼東西,
故手動加入其他要排除的資料夾。

匯出範本專案

執行 dotnet CLI 指令

dotnet new install .\

出現下面的訊息就是成功了。

打包套件

剛剛我們建立好了專案範本,現在要打包成 NuGet 套件包。

調整目錄結構

建立一個空資料夾,裡面要新增一個 .csproj 和一個 templates 資料夾。

例如下圖這樣:

templates 資料夾就放上面做好的專案範本。

撰寫套件描述

開啟外層的的 .csproj 檔案,加入必要的 XML 格式標籤。
參考官方教學提供的範例來調整。

套件描述範例

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <PackageId>PamisWang.Template.WebAPI</PackageId>
        <PackageType>Template</PackageType>
        <PackageVersion>0.0.3</PackageVersion>
        <Title>Pamis Wang Template Web API</Title>
        <Authors>Pamis Wang</Authors>
        <Description>Web API 範本</Description>
        <PackageTags>dotnet-new;templates</PackageTags>
        <PackageReadmeFile>README.md</PackageReadmeFile>
        <PackageIcon>favicon.png</PackageIcon>
        <RepositoryUrl>https://github.com/pamiswang/PamisWangTemplateWebAPI</RepositoryUrl>
        <PackageReleaseNotes>修正套件的目標框架與補上相依套件</PackageReleaseNotes>
        <PackageLicenseExpression>MIT</PackageLicenseExpression>

        <TargetFramework>net6.0</TargetFramework>

        <IncludeContentInPack>true</IncludeContentInPack>
        <IncludeBuildOutput>false</IncludeBuildOutput>
        <ContentTargetFolders>content</ContentTargetFolders>
        <NoWarn>$(NoWarn);NU5128</NoWarn>
        <NoDefaultExcludes>true</NoDefaultExcludes>
    </PropertyGroup>

    <ItemGroup>
        <Content Include="templates\**\*" Exclude="templates\**\bin\**;templates\**\obj\**" />
        <Compile Remove="**\*" />
        <None Update="favicon.png" Pack="true" PackagePath="\" />
        <None Update="README.md" Pack="true" PackagePath="README.md" />
    </ItemGroup>

    <ItemGroup>
        <PackageReference Include="Dapper" Version="2.0.143" />
        <PackageReference Include="MailKit" Version="4.1.0" />
        <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="5.1.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.10" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.10" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.10" />
        <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
        <PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" />
        <PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.15" />
        <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.4" />
        <PackageReference Include="Oracle.EntityFrameworkCore" Version="7.21.11" />
        <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" />
        <PackageReference Include="Razor.Templating.Core" Version="1.8.0" />
        <PackageReference Include="RestSharp" Version="110.2.0" />
        <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
        <PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="6.5.0" />
        <PackageReference Include="System.DirectoryServices" Version="7.0.1" />
        <PackageReference Include="System.DirectoryServices.AccountManagement" Version="7.0.0" />
        <PackageReference Include="System.DirectoryServices.Protocols" Version="7.0.1" />
    </ItemGroup>

</Project>

套件描述說明

列出一些會用到的,更多的屬性標籤與用法請參考官方文件。

屬性名稱描述
PackageId套件名稱或識別碼。
PackageType指出套件的封裝類型
PackageVersionNuGet 套件版本。
Title套件的簡短標題
Authors以逗號分隔的套件作者清單
Description套件的描述。
PackageTags以空格分隔的標記與關鍵字清單
PackageReadmeFile套件讀我檔案的路徑。
PackageIcon套件圖示影像檔的路徑。
RepositoryUrl用來建置封裝的存放庫 URL
IsPackable指定是否可封裝專案
EnableDefaultContentItems設定是否要啟用 SDK 型專案預設排除的檔案設定
NoDefaultExcludes設定不要排除 NuGet 文件以及以點開頭的檔案和資料夾,例如 .svn 和 .gitignore。
IncludeContentInPack類型 Content 的專案是否自動包含在產生的套件中。預設為 true。
IncludeBuildOutput決定是否應該在套件中包含組建輸出組件。
ContentTargetFolders套件產生的檔案預設會放在 content
TargetFramework設定可確保 MSBuild 會在您執行 pack 命令以編譯和封裝專案時正常執行。
PackageReference指定套件相依性
Content設定有哪些檔案要被打包或被排除
None Update排除指定檔案被打包到 content

打包套件

在專案目錄下輸入指令就會開始打包

dotnet pack

打包成功的話預設會在 \bin\Debug 產生 .nupkg 檔案。

安裝套件

當套件打包好之後可以直接在本機進行安裝

dotnet new install [nupkg的檔案路徑]

使用範本

安裝好之後就可以來測試看看,
首先查詢專案範本列表看有沒有安裝成功。

dotnet new list

建立專案指令後看到成功建立專案項目。

dotnet new pamis-webapi

懶得打指令的也可以從 Visual Studio 的專案項目畫面做選擇
只是不懂為什麼我家貓貓臉變黑了......

發佈到 NuGet 上

首先要註冊帳號
接著右上角的上傳

上傳完畢等伺服器建立索引就會出現套件頁面了

不過目前 NuGet 上傳後就不能刪除了 XD

後記

撰寫這篇文章的時候花很多時間在排除套件打包的問題,
因為微軟官方文件關於建立範本套件open in new window的教學是基於主控台為例子
而每種專案內容的專案描述都有很多預設設定要另外查。
所以整個套件打包的過程是各種坑,
不過還好 dotnet CLI 的錯誤訊息都滿清楚的,
只要跟著訊息去逐一解決就會成功。

參考資料

範本專案

教學課程:建立專案範本open in new window
教學課程:建立範本套件open in new window
dotnet new 的自訂範本open in new window
自訂 dotnet new 專案範本的重要觀念與範例open in new window
Reference for template.jsonopen in new window

發布範本

NuGet 以目標的形式 MSBuild 封裝和還原open in new window
.NET 專案 SDKopen in new window
使用 MSBuild 建立 NuGet 套件open in new window
套件撰寫最佳做法open in new window

上次編輯於:
貢獻者: pamis,EXMAIL\pamis,Pamis Wang