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

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

(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 リリース早く来てくれ!!