🐥note.

小鳥とMicrosoft <3 なエンジニアの技術Blog📚

.NET Core Project TemplateとNuget Packageの作り方

ちょっとしたWPFアプリを複数個作る機会があり、同じような構成のWPFプロジェクトを何個も作るのが大変面倒だったので、Project Templateを作りました。

忘れないうちにProject Templateの作成と、そのProject TemplateをNuget Package化する方法について残しておきたいと思います。
※なおNugetで配布するのではなく、個人的に使いまわす目的でNuget Package化します。

ちなみに、こんな感じのWPFアプリが生成されるTemplateです。

f:id:piyo_esq:20200109082115p:plain
Templateで生成したWPFアプリの画面

目次

成果物

今回作成したtemplateは以下に保存しています。

github.com

作成するTemplate

今回は例として、下記4つのPackageを組込んだ .NET CoreのWPF Projectを作成します。

※4つと言いつつSerilog.Sinks.FileSerilog.Settings.AppSettingsも使用しています。前者はLogのファイル出力機能, 後者はapp.configからLoggingの設定を変更するものです。

Prism.Plugin.Loggingを見るとApp CenterApplication InsightsのLoggerもあるんですねぇ

Project Templateの作成

作業用フォルダを作成します

mkdir workingDir\templates
cd workingDir\templates

WPF Projectの作成

まずはTemplateとなるWPF Projectをtemplatesフォルダ以下に作成します。

dotnet new sln -n BaseTemplate
dotnet new wpf -o BaseTemplate.App
dotnet sln BaseTemplate.sln add .\BaseTemplate.App

Project名がBaseTemplateである点に留意してください。
後記するtemplate.configsourceNameキーの値と同じである必要があります。

WPF Projectの作成過程は省略します。

template.configの作成

Microsoft Docsを参考に進めます。

docs.microsoft.com

templatesフォルダ以下に.template.configフォルダを作成します。

mkdir .template.config

.template.configフォルダ内にtemplate.jsonを作成します。
各設定項目の内容はMicrosoft Docsを参照してください。

{
    "$schema": "http://json.schemastore.org/template",
    "author": "piyosi",
    "classifications": [ "WPF" ],
    "name": "Modern WPF Template",
    "identity": "Template.WPF.Modern.Piyosi.CSharp",
    "shortName": "ModernWPF",
    "tags": {
      "language": "C#",
      "type":"project"
    },
    "sourceName": "BaseTemplate",
    "preferNameDirectory": true
}

注意点としては、TemplateとなるWPF Project内の全ての文字列はsourceNameで指定した文字列に置換される点です。
※ファイル名含む

他にも生成時のオプションコマンドの追加など、色々できるようです。
以下のサンプルが参考になるかと思います。

github.com

Project Templateのインストール

下記コマンドで作成したProject Templateをインストールしてみます。

dotnet new -i .\

dotnet newで表示されるTemplateの一覧内にtemplate.confignameまたはshorNameで指定したTemplateが表示されていれば追加成功です。

もしdotnet newで探しにくい場合はdotnet new -uコマンドを使用してください。
追加した順にTemplateが降順表示されます。

追加したTemplateで実際にプロジェクトを作成してみましょう。

dotnet new <Template名> -o test -n SampleWPF

意図したProject名(上記例ではSampleWPF)で作成されれば成功です。

Project Templateのアンインストール

インストールしたTemplateを削除するには下記コマンドを実行します。

dotnet new --uninstall

インストール済みのTemplateが降順表示されます。
Uninstall Command:に記載されたコマンドを実行することでTemplateをアンインストールできます。

  C:\Users\piyoe\work\dotnet\workingDir\templates
    Templates:
      Modern WPF Template (ModernWPF) C#
    Uninstall Command:
      dotnet new -u C:\Users\piyoe\work\dotnet\workingDir\templates

Project TemplateのNuget Package作成

作成したWPF ProjectのTemplateをNuget Package化します。

引き続き先程のMicrosoft Docsを参考に進めます。

Nuget Package作成用Projectの設定

workingDirで以下のコマンドを実行します。
Program.csは不要なので削除します。

dotnet new console -n nugetTemplate
rm Program.cs

nugetTemplate.csprojを開き以下のように編集します。

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

 <PropertyGroup>
    <PackageType>Template</PackageType>
    <PackageVersion>1.0</PackageVersion>
    <PackageId>Template.WPF.Modern.Piyosi.CSharp</PackageId>
    <Title>Modern WPF Template</Title>
    <Authors>piyosi</Authors>
    <Description>Modern WPF Template of .NET Core</Description>
    <PackageTags>dotnet-new;templates;wpf;</PackageTags>

    <TargetFramework>netcoreapp3.1</TargetFramework>

    <IncludeContentInPack>true</IncludeContentInPack>
    <IncludeBuildOutput>false</IncludeBuildOutput>
    <ContentTargetFolders>content</ContentTargetFolders>
  </PropertyGroup>

  <ItemGroup>
    <Content Include="templates\**\*" Exclude="templates\**\bin\**;templates\**\obj\**" />
    <Compile Remove="**\*" />
  </ItemGroup>

</Project>

PackageIdTitle, Authrosなどは適宜変更してください。

Contentで指定したIncludeExcludeのパスがWPF ProjectのTemplateのパスになっていることを確認して下さい。

Nuget Packageのビルド

BuildしてPackします。

dotnet build
dotnet pack

github.com

bin\Debug以下に*.nupkgのファイルが生成されます。
packではReleaseビルドしない慣習っぽい?

Nuget PackageのProject Templateのインストール

生成された*.nupkgdotnet new -iでインストールします。

dotnet new -i <nupkgファイル>

Nuget PackageのProject Templateのアンインストール

アンインストールする際は先程と同様dotnet new -uでOKです。

dotnet new -u <nupkgファイル>

おわり

ModernWPFUIよくないですか?