やる気駆動型エンジニアの備忘録

WPF(XAML+C#)の話題を中心に.NET/Android/CI やたまに趣味に関するブログです

Azure Pipelines で.NET Core 3.0 Preview をビルドする

前回.NET FrameworkWPF プロジェクトを.NET Core 3.0 Preview へ移行したのですが、そのときAzure Pipelines ではビルドできないと思っていました。

iyemon018.hatenablog.com

しかし、@kkamegawa さんからのアドバイスを頂き、自動ビルドができることがわかりました。

今回はその手順をまとめます。

実行手順

まずはgrobal.jsonファイルを作成します。 このファイルは実行環境に複数の.NET Core SDK が存在する場合にgrobal.jsonに定義したバージョンのSDKを使用する事ができます。

docs.microsoft.com

grobal.jsonを作るにはプロジェクト フォルダ上でコマンドプロンプトを起動して以下のコマンドを実行します。

dotnet new globaljson --sdk-version <.NET Core のバージョン>

例えば.NET Core Preview4 の場合は以下のようになります。

dotnet new globaljson --sdk-version 3.0.100-preview4-011223

次にAzure Pipelines に.NET Core SDK Installer タスクを追加します。 タスクの設定はこんな感じ。

f:id:iyemon018:20190422221050p:plain

YAML だとこんな感じ。

steps:
- task: DotNetCoreInstaller@0
  displayName: 'Use .NET Core runtime 3.0.0-preview4-27615-11'
  inputs:
    version: '3.0.100-preview4-011223'

この.NET Core のバージョンは以下のページを参照してください。 注意すべき点としてSDK とRuntime でバージョン番号の表記が若干異なります。 タスクのPackage to installの種別を確認しておきましょう。

github.com

なお、.NET Core 3.0 なのでVS 2019 にしないとビルドできませんのでご注意を。

あとはビルドをキューに登録して実行すればOKです。

(WPF).NET Framework で作ったアプリを.NET Core 3.0 Preview へ移行した

.NET Framework で作成していたWPF アプリを.NET Core 3.0 Preview へ移行してみました。 というのもxUnit.NET でテストコードを書いていたんですが、.NET Framework だとテストを実行するにはxunit.console.runner を実行するしかなく、Azure Pipelines でバージョンアップ時に書き換えるのがめんどいしカバレッジも自力で集計・レポート作成設定しないといけないのでなかなかに辛いのです。 で、せっかくVS 2019 Community もリリースされたので使ってみようと思いました。

なお、このエントリで試したことは2019年4月21日時点のものです。

.NET Framework版のプロジェクト構成

移行前のソリューション構成です。

f:id:iyemon018:20190421152109p:plain

それぞれのプロジェクト構成はこんな感じ。

プロジェクト名 フレームワーク 用途
Cartica.App .NET Framework 4.7.1 アプリのエントリポイント。起動時のexe。
Cartica.Controls .NET Framework 4.7.1 UI 関連の機能。
Cartica.Core .NET Standard 2.1 ビジネスロジックとか。
Cartica.Domain .NET Framework 4.7.1 ドメイン関連の機能とか値オブジェクトとか。
Cartica.Domain.Net .NET Framework 4.7.1 ドメイン関連のうちWEB API 使うものとか。
Cartica.Encryptions .NET Framework 4.7.1 暗号化、復号化関連。
Cartica.Core.Tests .NET Core 2.1 .NET Standard 用のテストプロジェクト。
Cartica.Tests .NET Framework 4.7.1 .NET Framework 用のテストプロジェクト。
Tests.Core .NET Standard 2.0 テストコードの汎用機能。

なお、今回移行対象に考えているのは"Cartica.App"プロジェクトです。

.NET Coreへの移行手順

まず、今回移行に伴い参考にした資料はこちらです。

docs.microsoft.com

下準備

  1. プロジェクトが.NET Core へ移行可能か検証する。 検証には.NET Portability Analyzer を使用します。 docs.microsoft.com
  2. .NET Core 3.0 Preview をインストールする。 .NET Core 3.0 Preview のインストールは以下から。 dotnet.microsoft.com
  3. Visual Studio 2019 をインストールする。 初期設定ではVS 2019 で.NET Core 3.0 Preview を使えないので、以下のページの「RC 版で .NET Core 3.0」にある通りに設定しましょう。 ufcpp.net

移行手順

  1. dotnet new wpfコマンドを使って.NET Core のWPF プロジェクトを作成する。
  2. 作成した.csproj ファイルの内容を.NET Framework の.csproj にコピペする。
  3. NuGet パッケージを参照しているのであれば、.csproj に記載する。packages.config ファイルとタグが若干違うので目Grep で書き換える。(ここめんどい)
  4. Properties/AssemblyInfo.csが未変更なら不要なので削除する。私の場合はInternalsVisibleTo使ってたので、そのコードだけ残して削除しました。
  5. NU1701の警告がめっちゃ出てくるので、.NET Framework 互換モード で警告を非表示にする。(ここはOSS の対応待ち or .NET Core 向けあるならそっち使う)

さて、ここまではよくブログなどに載せられている手順ですが、私のプロジェクト上では更に以下の手順を実施しました。 プロダクトによっては以下の手順は不要だと思います。

追加した移行手順

  1. ユニットテスト プロジェクトの参照を.NET Framework 用プロジェクトから.NET Core 側に移行した。
  2. System.Windows.Interactivity.dllを参照していたので、XamlBehaviors for WPF のNuGet パッケージを追加した。
    XAML に使用している場合、namespace はxmlns:interactions="http://schemas.microsoft.com/xaml/behaviors"に変更しておきます。xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"こっちはいらないので削除しておきましょう。
  3. 複数プロジェクトあったので、下位のプロジェクトから順にクリーン + リビルドを実施する。

これでビルドが成功し、実行すると動くようになりました。

移行後の.csproj

.NET Core 3.0 への移行で若干迷ったのが.csproj ファイルの編集なんですが、その理由がMS 公式リファレンスや個人ブログでは.csproj の中身が見えないのでどこに追記すればいいかわかんないんですよね。 なので、今回私が作成した.csproj ファイルはここに載せておきます。

タグの意味とかは移行手順の参考資料に記載しているのでそちらを御覧ください。

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

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <UseWPF>true</UseWPF>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    <AssemblyName>Cartica.App</AssemblyName>
    <RootNamespace>Cartica.App</RootNamespace>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="CommonServiceLocator" Version="2.0.4" />
    <PackageReference Include="LiveCharts" Version="0.9.7" NoWarn="NU1701" />
    <PackageReference Include="LiveCharts.Wpf" Version="0.9.7" NoWarn="NU1701" />
    <PackageReference Include="MaterialDesignColors" Version="1.1.1" NoWarn="NU1701" />
    <PackageReference Include="MaterialDesignThemes" Version="2.5.0.1205" NoWarn="NU1701" />
    <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.0.1" NoWarn="NU1701" />
    <PackageReference Include="Prism.Core" Version="7.1.0.431" />
    <PackageReference Include="Prism.Unity" Version="7.1.0.431" NoWarn="NU1701" />
    <PackageReference Include="Prism.Wpf" Version="7.1.0.431" NoWarn="NU1701" />
    <PackageReference Include="Unity.Abstractions" Version="3.3.1" />
    <PackageReference Include="Unity.Container" Version="5.8.11" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Cartica.Controls\Cartica.Controls.csproj" />
    <ProjectReference Include="..\Cartica.Core\Cartica.Core.csproj" />
    <ProjectReference Include="..\Cartica.Domain.Net\Cartica.Domain.Net.csproj" />
    <ProjectReference Include="..\Cartica.Domain\Cartica.Domain.csproj" />
    <ProjectReference Include="..\Cartica.Encryptions\Cartica.Encryptions.csproj" />
  </ItemGroup>

</Project>

できないこと

まだプレビュー版だからなのか、以下は対応できませんでした。

  1. .NET FrameworkWPF コントロールライブラリの.NET Core 3.0 対応

2. Azure Pipelines でVS 2019 Hosted で自動ビルド

2019年4月22日 追記

Azure Pipelines で.NET Core 3.0 Preview の自動ビルドは可能でした。 その手順を以下にまとめましたのでご確認ください。

iyemon018.hatenablog.com

ここまで追記

この辺は正式版がリリースされてからの話だと思うので楽しみに待ってましょう。

移行の感想

ぶっちゃけブログなどでは移行が簡単そうに書いていますが、それはWPF プロジェクトが1プロジェクトしかないときと考えたほうがいいでしょう。 WPF コントロールライブラリは.NET Core への移行が現時点では不可能なので使用している場合は無理に.NET Core へ移行する必要もないでしょう。

あと、Azure Pipelines もビルドできないので使用している方はご注意ください。

結論、 .NET Core 3.0 リリース早く来てくれ!!

ErgoDox EZ のキーキャップを変えてみた(TALP KEYBOARD)

以前、ErgoDox EZ のキーキャップを変えたのですが、そのときはDCS プロファイルだったたのでカラー バリエーションが少ない、海外でしか購入できないといった問題点がありました。 なので日本でキーキャップを購入できるところはないかなーと探していたところ、TALP KEYBAROD というサイトを見つけました。

talpkeyboard.stores.jp

カスタマイズした結果

先に購入したキーキャップを差し替えた私のErgoDox EZ をお見せしましょう。

f:id:iyemon018:20190420160152j:plain

自然界的には間違いなく毒持ちな配色となりました( ・`ω・´)+

(まぁ、変えたのは3ヶ月近く前のことなんですが…)

TALP KEYBOARDについて

主にメカニカルキーボードのキーキャップや自作キーボードパーツを提供されています。 DCS プロファイルのキーキャップはないのですが、DSA プロファイルであればカラーバリエーションが大変豊富です。 また、1.5u, 1.25u サイズやキーキャップのセット販売もあり見ているだけでポチってしまいそうなほどです。 Twitter もやっているそうなので、売り切れた場合でも再販の情報をいつでも見れます。

twitter.com

購入したキーキャプ

今回購入したキーキャップはこんな感じ。

f:id:iyemon018:20190420162020p:plain

全体的に写真で見るよりも実物のほうが若干明るい色のように見えます。 (モニタのせいかも?)

やっぱりパソコンを長時間使う職業柄、持ち物にはこだわりが強くなっていくのでちょっと気分を変えたいと言うときにお手軽な方法としてキーキャップを変えるというのはなかなかいい手段かと思います。 これを見たあなたもキーキャップ沼に入ってみてはいかがでしょうか?

(Azure DevOps)Azure Pipelines で.NET Framework + xUnit のユニットテストの実行と集計方法について

.NET Framework を使ってちょっとしたプログラムを作っていたのですが、ユニットテスト プロジェクトにxUnit を使った場合のAzure Pipelines のタスク設定方法がわからなかったので備忘録として残しておきます。 Azure Pipelines でのテスト タスクは.NET Core のサンプルとかはよくブログに書いていることが多いんですが、.NET Framework に関する内容はかなり少ないです。 ちなみに.NET Core でのテストであればdotntet testコマンドで実行できるので実はそれほど迷わないんですよね~。

動作環境

予めxunit.runner.consoleはNuGet から追加しておく必要があります。

Azure Pipelines からタスクを追加する

初見だとVisual Studio Testを追加してしまいがちなんですが。実はこれが罠。 Visual Studio Testだと、xUnit プロジェクトのビルドとテストの実行はしてくれますが、テスト結果を集計してくれません。 そもそもvstest.console.exeが実行されてしまいます。

<実行されるログの例>

vstest.console.exe 
"D:\a\1\s\Tests\hogehoge\bin\Release\hogehoge.Tests.dll"
/EnableCodeCoverage
/logger:"trx"
/TestAdapterPath:"D:\a\1\s"
/InIsolation
Starting test execution, please wait...

やっぱりテストを実行したからにはテスト結果を集計してDashboards とかに表示したいですよね?

じゃあ、どうやるの?といろいろ試した結果、以下の方法で実現できました。

iyemon018.hatenablog.com

上記はJenkins を使ったやり方ですが、Azure Pipelines にも応用できます。 具体的には以下の通り。

  1. タスクからCommand Lineを追加する。
  2. Scriptを貼り付ける。
  3. 他はそのままでOK
  4. タスクからPublish Test Resultsを追加する。
  5. Test result formatxUnitを選択し、Test results filesに2.で設定したテスト結果ファイルパスを入力する。
  6. 他はそのままでOK

Scriptはこんな感じです。

packages\xunit.runner.console.2.4.0\tools\<.NET Versionによって異なる>\xunit.console.exe
$(System.DefaultWorkingDirectory)\Tests\<ユニットテスト プロジェクト フォルダ>\bin\$(BuildConfiguration)\<テストアセンブリ名>.dll -xml ./test-results.xml

.NET Framework のバージョンやプロジェクトの名前によって必要な箇所は適宜修正して使ってください。 xunit.runner.console.exe を使って-xml <テスト結果ファイル名>としてやればいいです。 このテスト結果ファイル名Publish Test Resultsでも使用するので注意してください。

この状態でビルドを実行すると、[Pipelines] - [Builds] - [History] - [Tests] にテスト結果が集計されます。 ここまで来たらDashboards のテスト結果ウィジェットにも結果が反映されるようになります。

f:id:iyemon018:20190317155622p:plain

めでたしめでたし。

(WPF)Live Charts をMVVM で使ってみる -円グラフ-

野暮用でグラフを使ったWPF アプリ開発をしたかったので前々から気になってたLive Charts を使ってみました。 私が調べた限りだとLive Charts をMVVM で使うサンプルの数が乏しい(特に"PieChart")ので備忘録がてらここに残しておきます。

Live Charts って?

lvcharts.net

.NET 向けのインタラクティブなグラフ コンポーネントです。 2019年3月現在ではWPF、およびWindows Forms に対応しています。

今後はUWP やXamarin にも対応予定だそうです。 特徴としてインタラクティブ、つまり描画やプロット、マウスオーバー時にアニメーションしてデータを可視化してくれます。

また、追加のパッケージを購入することで数百万のポイントをプロットしてもパフォーマンスを低下することなく描画が可能なんだそうです。(未検証) なお、ライセンスはMIT です。

github.com

  • ドキュメント

lvcharts.net

動作環境

このエントリではLive Chart Ver.0.9.7を使用しています。

インストール

ドキュメントページにもありますが一応。

Install-Package LiveCharts.Wpf

円グラフを描く

今回はPrism を使ってMVVM アーキテクチャで円グラフを作成します。 ざっくり今回の内容を説明すると、記録された作業時間の合計を1日毎に比較してどのくらい時間差があるかを見ています。 データは2日分しかないですが、サンプルなので許してください。

gistdabe9aa3e6286a28dc2e4bc48912bc25

[実行結果]

f:id:iyemon018:20190303172336p:plain

XAML では、以下の名前空間を定義しておきましょう。

xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"

XAML で使用したPieChart のプロパティは以下のとおりです。

  • SeriesColors

    グラフの色を定義するためのコレクション。

  • LegendLocation

    凡例の位置。LiveCharts.LegendLocation 型で定義されていて、"なし" or "上" or "下" or "左" or "右" からいずれかを選択します。

  • Series

    グラフの値をプロットするためのシリーズです。これはグラフごとに1要素に専用の型が定義されていて、円グラフの場合はLiveCharts.Wpf.PieSeriesとなっています。

  • StartingRotationAngle

    グラフをプロットする開始角度です。なぜかは分かりませんが初期値が45になっています。その方がイケてるからなんでしょうか?

さて、この内ちょっと面倒なのがSeriesです。 これらをMVVM で設定するサンプルがほぼ無く、公式ドキュメントでもべた書きです。

いろいろ試した結果、MainWindowViewModel クラスのようになりました。

Series が割と厄介で、ぶっちゃけPieSeriesクラスのどのプロパティがどこに反映されるのかよく分かりません。 私が調べた限りだとこんな感じでした。

  • Title

    判例に使用される。デフォルトだとツールチップにも表示される。

  • Values

    グラフにプロットする値。LiveCharts.ChartValues型で定義されているのでintdoubleでプロットできます。

  • LabelPoint

    円グラフの1データ上に表示するラベルの表記を設定します。デフォルトはnullとなっており、何も表示されません。 このプロパティの型はFunc<LiveCharts.ChartPoint, string>となっていて、LiveCharts.ChartPointからプロットしたTitleValuesを参照することができます。

  • FontSize

    どこのフォントサイズ?って思いますが、上記のLabelPointを表記する際のフォントサイズです。

このようにLive Charts はMVVM のサンプルこそ少ないものの、やろうと思えば全然問題なくMVVM でも使用することができます。 しかし、個人的にはViewModel がLiveCharts.SeriesCollectionに依存するのに違和感があります。 対策するのであれば、Converter などを使用してModel → PieSeries にするとかでしょうか…。しかし、テスタブルにしやすい代わりに汎用性が犠牲になりそうですね~。グラフってだいたいデータに依存しますし。

であれば、いっその事MVVM でなくてコードビハインドにべた書きでも良いような気はします。(この記事の存在意義がなくなってしまいますが!) この辺はプロダクトごとの設計思想次第でしょうね。

Live Charts 自体は標準でグラフィカルなグラフが描けるので、.NET アプリでグラフを作る場合にはもってこいではないでしょうか? ご興味があればぜひ使ってみてください♪♪

今回使用したサンプルはこちら↓↓↓↓↓

github.com