【Visual Studio】共有プロジェクトを含むマルチプロジェクトテンプレートの作り方

こんにちはー、ニアです。

今回は、共有プロジェクトを含むマルチプロジェクトテンプレートを作成する方法を紹介します。

カスタマイズしたプロジェクトはVisual Studioの機能で簡単にテンプレートを作れるけど、先日作ったChronoir_net.Chronica.AndroidWithWearのような共有プロジェクトを含むテンプレートの作成には少しコツがいるのよ。

1. 環境

参考までに私の場合の環境をここに載せておきます。

  • Windows 10 Pro
  • Visual Studio 2017 バージョン15.5.7

この記事では、Chronoir_net.Chronica.AndroidWithWearを例に、1つの共有プロジェクト&2つのプロジェクトを持つマルチプロジェクトテンプレートを作っていきます。

2. 共有プロジェクトを含むマルチプロジェクトテンプレートを作成

まずは、その3つのプロジェクトをそれぞれテンプレートとしてエクスポートします。メニューバーから「プロジェクト」>「テンプレートのエクスポート」を選択します。

ウィザード画面では、「プロジェクトテンプレート」の項目を選択し、下のドロップダウンからエクスポートするプロジェクトを選択します。

テンプレートのオプションでは、「テンプレートを自動的にVisual Studioにインポート」のチェックを外して完了ボタンを押します。

Nia02.png
ここのテンプレート名やアイコンイメージのパスは使わないので、そのままで大丈夫ですよ!

エクスポートしたテンプレートファイル(zip)をそれぞれ解凍します。

マルチプロジェクトのルートとなるVSTemplateファイルを作成します。

<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="ProjectGroup">
  <TemplateData>
    <Name>Android with Wear 2.0 App (Shared Project)</Name>
    <Description>A multi-project template for building apps for Android (API level 19 or higher) and Android Wear 2.0 (API level 25 or higher) with Xamarin.Android.
This template contains shared projects, and source code can be shared between projects.</Description>
    <ProjectType>CSharp</ProjectType>
    <ProjectSubType>
    </ProjectSubType>
    <SortOrder>1000</SortOrder>
    <CreateNewFolder>true</CreateNewFolder>
    <DefaultName>App</DefaultName>
    <ProvideDefaultName>true</ProvideDefaultName>
    <LocationField>Enabled</LocationField>
    <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
    <CreateInPlace>true</CreateInPlace>
    <Icon>__TemplateIcon.ico</Icon>
    <PreviewImage>WithWear.png</PreviewImage> 
  </TemplateData>
  <TemplateContent>
    <ProjectCollection>
		<ProjectTemplateLink ProjectName="$safeprojectname$">AndroidWithWear\MyTemplate.vstemplate</ProjectTemplateLink>
		<ProjectTemplateLink ProjectName="$safeprojectname$.Mobile" CopyParameters="true">AndroidWithWear.Mobile\MyTemplate.vstemplate</ProjectTemplateLink>
		<ProjectTemplateLink ProjectName="$safeprojectname$.Wear" CopyParameters="true">AndroidWithWear.Wear\MyTemplate.vstemplate</ProjectTemplateLink>
	</ProjectCollection>
  </TemplateContent>
</VSTemplate>

1行目の<VSTemplate>のType属性にはProjectGroupを指定します。

<TemplateData>~</TemplateData>の中にプロジェクトテンプレートの名前や説明、アイコンファイルのパスを入力します。

<TemplateContent>~</TemplateContent>の中に<ProjectCollecttion>を入れて、その中にテンプレートに含めるプロジェクトのVSTemplateのパスの定義を入力します。

ProjectTemplateLink 概要
ProjectName属性 テンプレートから作成した時のプロジェクト名を定義します。
テンプレート変数$safeprojectname$は、プロジェクト作成ダイアログでユーザーが入力したプロジェクト名がセットされます。

 

 

また、プロジェクトのVSTemplateファイル側のテンプレート変数$safeprojectname$に、この属性の値がセットされます。
(上記の例では、Mobile側のVSTemplateでは$safeprojectname$ =【プロジェクト名】.Mobile、Wear側のVSTemplateでは$safeprojectname$ =【プロジェクト名】.Wearになります。)

CopyParameters属性 この属性値をtrueにすると、プロジェクトのVSTemplateファイルで、ルート側のVSTemplateのテンプレート変数(プロジェクト名なら「$ext_safeprojectname$」)を使用することができます。
プロジェクトのVSTemplateファイルのパス(相対パス)を指定します。

Chronoir_net.Chronica.AndroidWithWearでは、MobileとWearプロジェクトが共有プロジェクトを参照する必要があるので、CopyParameters属性をtrueにしてそれらのプロジェクトのVSTemplateから共有プロジェクトの名前を取得できるようにします。

次に、MobileとWearプロジェクトファイルにて、VSTemplateファイルとプロジェクトファイルをそれぞれ編集します。

VSTemplateでは、<TemplateData>~</TemplateData>の中に<CreateInPlace>を追加して値をtrueに設定します。省略すると、共有プロジェクトを参照できず、プロジェクトの作成に失敗する原因になります。

<CreateInPlace>true</CreateInPlace>

プロジェクトファイルでは、共有プロジェクトへの参照部分を$safeprojectname$から$ext_safeprojectname$に修正します。

<Import Project="..\$safeprojectname$\$safeprojectname$.projitems" Label="Shared" />
↓
<Import Project="..\$ext_safeprojectname$\$ext_safeprojectname$.projitems" Label="Shared" />

さらに、NuGetパッケージの参照パスを修正します。(テキスト置換機能で修正したほうが早いかも)

<Reference Include="Xamarin.Android.Wear, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
  <HintPath>..\packages\Xamarin.Android.Wear.2.0.1.1\lib\MonoAndroid70\Xamarin.Android.Wear.dll</HintPath>
</Reference>

↓

<Reference Include="Xamarin.Android.Wear, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
  <HintPath>..\..\packages\Xamarin.Android.Wear.2.0.1.1\lib\MonoAndroid70\Xamarin.Android.Wear.dll</HintPath>
</Reference>
Nia04.png
マルチプロジェクトテンプレートから作成すると、各プロジェクトファイルはソリューションフォルダーの2段分中に配置される(エクスポートする時の位置より1段深い)ので、そのままではNuGetパッケージを上手く参照できないんです。
NuGetパッケージを多く使用しているWearプロジェクトでは、パスの修正が面倒くさかったよ~

あとは、プロジェクトのフォルダーとルートのVSTemplate(必要に応じてアイコンファイルも)をzipファイルに圧縮してテンプレートの完成です。

テンプレートを作成したら、実際にプロジェクトテンプレートフォルダーに入れて、プロジェクト作成の動作確認をしてみましょう。

Chronoir_net.Chronica.AndroidWithWearのリポジトリ内のTemplatesフォルダー内から、VStemplateやプロジェクトファイルの中身が見れますので、参考までにどうぞ。

GitHub: https://github.com/Nia-TN1012/AndroidWithWear

.NET Standardライブラリプロジェクトの場合

共有プロジェクトの代わりに、.NET Standardライブラリプロジェクトを含むマルチプロジェクトテンプレートを作成する場合、.NET Standardプロジェクト側のVSTemplateファイルにも、<CreateInPlace>を追加してtrueに設定する必要があります。

テンプレートのエクスポートで出力したままの状態で含めると、プロジェクトを作成した時に、.NET Standardプロジェクトのソースコードなどが追加されず、すっからかんになります。

Nia08.png
何者なんだ、<CreateInPlace>。。。

3. おわりに

今回は、共有プロジェクトを含むマルチプロジェクトテンプレートを作成する方法を紹介しました。

単体のプロジェクトテンプレートと比べて、VSTemplateの仕組みをより熟知する必要があり、プロジェクトファイルの編集箇所が多くてちょっと大変だけど、これを使いこなせると、クロスプラットフォームアプリ向けのテンプレート作りがとても捗るはず!

それでは、See you next!

4. 参考サイト

この記事をシェアする
Chronoir.netのRSSフィードを購読する

ニア(Nia)

ゲーム系の開発&運用エンジニア(目指すはフルスタック)。主にC#(Unity)/PHPを使っています。最近はDockerやKubernetes、プライベートではAndroid Wearアプリやモバイルアプリ開発(Xamarin)を探求中。好物は紅茶とコーヒー、シラス丼、趣味は写真撮影と音ゲーです

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください