2022年4月26日火曜日

FAC製作記 その4 MVVMフレームワークをPrismからCommunityToolkit.Mvvmに移行する

2021年11月に.NET 6がリリースされました。
FACも.NET 6でビルドし直して、ついでにあれこれ手を加えて、3月19日に.NET 6版をリリースしました。
今回は「あれこれ手を加えて」の1つ、MVVMフレームワークの移行についてです。

なお、今回からコード類はQiitaに載せることにしました。

MVVMフレームワークの移行についてはその2でも少し書きました。
その2のときは.NET 5対応に伴って、MVVM Light ToolkitからPrismに移行しました。
今回はタイトルの通り、PrismからCommunityToolkit.Mvvmに移行しました。

【移行した理由】
前回はMVVM Light Toolkitが.NET 5に対応しないから、という理由でした。
今回は少し理由が違っていて、Prismと一緒に使っていたライブラリが開発を終了したためです。

FACではPrismを使うにあたり、Prism.Unityを使っていました。
で、これを構成するDIコンテナのUnity Containerが、2021年11月9日付けで開発とメンテナンスを終了しました。
今でもNuGetからインストールすることはできますが、非推奨となっています。

Unity ContainerはDIコンテナなので、別のDIコンテナに切り替えることも考えました。
例えば、Unityと並んでPrismと統合されているDryIocとかがあります。
ですが、仕事で調べ物をしている最中に、偶然「Microsoft.Toolkit.Mvvm」というものに遭遇しました。
せっかくなのでこれを調べてみて、「MVVM Light Toolkitみたいじゃねえか!」ということで移行を決意しました。

【Microsoft.Toolkit.MvvmとCommunityToolkit.Mvvm】
調べて出てきたのは「Microsoft.Toolkit.Mvvm」、俺がFACで使っているのは「CommunityToolkit.Mvvm」です。
NuGetで「mvvm toolkit」とかで検索すると、同じアイコンで2つ出てきます。
安定版の最新バージョンはどちらも同じで、CommunityToolkit.Mvvmは新しいメジャーバージョンのプレビュー版があったりします。
どうやら将来的にはCommunityToolkit.*に統一される予定らしいということで、CommunityToolkit.Mvvmを使うことにしました。

【移行する】
結構力技でやりました。
一応順を追って行きます。

1. 参考にするためにMVVM Light Toolkitを使うアプリとCommunityToolkit.Mvvmを使うアプリを作る
いきなり脱線します。
というのも、FACではPrism.Unityを使うためにApp.xaml/App.xaml.csを書き換えていました。
書き換える前のコードなんか覚えていないので、丸写しするためにテスト用のアプリを作ったわけです。

2. NuGetで必要なライブラリをインストール
CommunityToolkit.MvvmとMicrosoft.Extensions.DependencyInjectionをインストールします。
後者はDIコンテナです。
Unity Containerから脱却するためのMVVMフレームワーク移行なので、DIコンテナは使い続けます。

3. App.xaml/App.xaml.csを書き換える
1.で作ったCommunityToolkit.Mvvm版のコードを丸写しします。
名前空間が違うのでそこだけ書き換えます。

4. ロケーターを用意する
Prism.UnityではApp.xaml.csでDIの設定をしていましたが、ばっさり削除してしまったのでどこかで設定する必要があります。
そこでViewModelLocatorに相乗りさせることにしました。
通常はViewModelsフォルダーにViewModelLocatorというクラスを用意します。
MVVM Light Toolkitの場合はNuGetでインストールするだけで自動生成してくれるファイルですね。
これにDIも含めた役割を持たせるために、プロジェクト直下にLocatorというクラスを用意しました。
ここにCommunityToolkit.MvvmのViewModelLocatorと、Microsoft.Extensions.DependencyInjectionのDIの設定をまとめてしまいます。
最後にApp.xamlでアプリのリソースにLocatorクラスを登録すればOKです。

5. ViewとViewModelを修正する
MVVMフレームワークを移行するので、ViewModelへの影響は避けられません。
また、FACの場合はViewとViewModelの紐づけにPrismの機能を使っていたので、これを削除する必要があります。
紐づけはMVVM Light Toolkitのころと同じく、ViewのDataContextをXAMLで設定することで実現します。

Gitのログを見てみると、2.~5.で約2時間半という感じでした。

.NET 5対応に伴ってPrismに移行したときには、また移行することがあるとは思ってもいませんでした。
MVVMフレームワークはアプリ作りの根幹にかかわることだけに、そうそう移行をするものではないですが、これもまた経験と捉えましょう。
MVVM Light Toolkitは気に入っていたので、同じ感覚で使えるのは嬉しいポイントですね。

今回のコードはこちらに載せました。


今日の1曲: