Prism 8 リリース【.NET Core WPF Prism MVVM 入門 2020】
Prism 8.0.0.1909 のリリース
Prism 8.0.0.1909 が 2020/10/22 にリリースされていました。
Prism 7.1 のリリースから 2 年を置いて久々のメジャーバージョンアップですが、Uno Platform のサポートが主な目的のようなので WPF にあまり影響は無いと考えて良いと思います。
管理人も現在連載中の .NET Core WPF Prism MVVM 入門 2020 で紹介しているサンプルを Prism 8 に入れ替えてみましたが、何のエラーも無くビルドができて画面も起動しました。
全ての動作を確認した訳ではないので「全く問題はありません」と言い切れないのが悲しい所ですが、Prism 8 で対応された Issue を確認した限りではバージョンアップしても問題なさそうな感じでした。
但し、通例だと 2 ~ 3か月以内に Bug Fix 版がリリースされる場合が多いので、不安だったり正に開発真っ最中のプロジェクトの場合は Bug Fix 版のリリースを待ってからバージョンアップしても良いと思います。
WPF での変更点
Prism 8 のリリースノートでは WPF に関係しそうな変更は以下の通りです。
- Prism.Logging 名前空間を全て削除
- レガシーブートストラップの削除
- 新しい PrismBootstrapper の追加
- InteractionRequest や WindowPopUpAction 等をリポジトリから物理削除
- ViewModelLocator.AutowireViewModel のデフォルト値が true に変更
- XAMLContainerProvider の追加
- .NET Core 3.1 に変更
- RegisterViewWithRegion へジェネリックメソッドを追加
- 複数の DialogWindow に対応
バグ修正等もありますが、Prism を使用して WPF アプリを作成する際に関連しそうなのは上記の 9 項目程度だと思います。
Prism 8 へのバージョンアップについて
最初に書いた通り、Prism 8 の最大目的は Uno Platform のサポートです。
Uno Platform は Xamarin.Forms をラップしたプラットフォームなので Xamarin.Forms 用の Prism.Forms には多くの変更が入っていますが、 WPF には目玉になるような変更はありません。とは言え、既存プロジェクトを更新する場合は多少の注意は必要なので、少しだけ掘り下げます。
Prism.Logging 名前空間の削除
Prism 8 WPF のリリースノートで唯一の破壊的変更が【Prism.Logging 名前空間の削除】です。
まあ、Prism.Logging を紹介しているサイトもあまり見かけませんし、このサイトのエントリでも紹介したことが無いので使っている人は多くないと思っていますが、Prism 7.x 系で Prism.Logging を使用している場合は代替手段を用意する必要があります。現状では【WPF に対応した Windows Template Studio】でも紹介した .NET Core Generic Host のログ機能を使うのがお手軽だと思うので、又その内紹介記事を書くかもしれません。
Bootstrapper について
Prism の起動時処理が Bootstrapper から PrismApplication に変わって 1 年以上経ちますが、未だに『prism unitybootstrapper』等の検索キーワードでこのサイトに来られる人も居らっしゃいます。PrismApplication については .NET Core WPF Prism MVVM 入門 2020 の step: 3 で詳しく紹介しているので、良ければ読んでください。
加えて、新たに PrismBootstrapper が追加されたようですがイマイチどんな場合に使用するのかよく分かっていません。リリースノートに関連した Issue を読むとおそらく Windows のサービスのような、起動時には画面を表示しないが、設定を変更する等のタイミングで Prism を使用した画面を表示するようなアプリに使用するのだろうと予想しています。間違っているかもしれませんが、詳しいことが分かれば記事にしたいと思います。
InteractionRequest や WindowPopUpAction 等の削除について
これはリリースノートには載っていませんが、見出しに書いたクラスが Prism から削除されました。見出しに書いた InteractionRequest や WindowPopUpAction だけでなく Prism のプルリク #1969 で挙がっているクラスが全て削除されています。
削除されたのは Ver. 7.2.0.1367 で Obsolete 指定されたクラスです。Prism の場合【Obsolete】が指定されたクラスは次バージョンで削除される事が多いのでビルドメッセージに【Obsolete】が表示された場合は代替手段の検討が必要だと思ってください。
.NET Core 3.1 に変更
Prism 自体を .NET Core 3.1 に変更したようですが、2020/11/2 現在、肝心の Prism Template Pack が Ver. 2.2.2 から更新されていないので、新規で作成する Prism Application や Prism Module は【.NET Core 3.0】をターゲットに作成される状態から変わっていません。.NET Core 3.1 で作成する場合は、相変わらずターゲットフレームワークを手作業で変更する必要があります。
その他機能追加関連
Prism 8 で WPF へ追加された新機能は『XAMLContainerProvider の追加』『RegisterViewWithRegion へジェネリックメソッドを追加』『複数の DialogWindow に対応』の 3 点です。『XAMLContainerProvider の追加』については XAML で DI コンテナからクラスを取得できる機能のようですが、使い所がピンと来ないのでとりあえず紹介する予定はありません。
『RegisterViewWithRegion へジェネリックメソッドを追加』に関しては、現在連載中の .NET Core WPF Prism MVVM 入門 2020 のどこかの記事を更新しようと思っています。
『複数の DialogWindow に対応』は管理人的に結構重要な機能追加だと思っています。Prism 7.2 から新たに追加された IDialogService から表示する DialogWindow は今までは 1 つの Window を使い回す事しかできませんでしたが、Prism 8 からは複数の DialogWindow を指定できるように変わったと解釈しています。
現状は実際に試した訳ではないので間違っているかもしれませんが、複数の DialogWindow を持てるようになったと言う事は、表示位置を保存・復元可能な DialogWindow と、メッセージボックス等のように常に OwnerWindow の中央に表示したい DialogWindow が持てるようになった事だと考えているので少し期待しています。
現時点(2020/11 現在)では連載がそこまで追いついていないので、紹介できるのはもう少し先になると思いますが、大して難しい機能ではないと思うので試してみてください。
まとめ的な
今回はこのサイトのメインコンテンツである WPF に関係する変更が多くなかったので、画像もサンプルコードも無い、つらつらと思い付いた文章を書いただけのエントリになりましたが、Prism 8 へのバージョンアップは WPF にも多少は意味があると思うので、状況が許す場合ならバージョンアップする方が良いと思います。
とりあえず今は最近始めたアニメの一覧作成にかまけて .NET Core WPF Prism MVVM 入門 2020 の記事公開が止まっていますが、step: 9 はなるべく早めに公開したいと思っています。
あと,当方では,製品ではなく,ユニットテスト専用のプロジェクトは画面は必要が無いので,以前はUnityBootStrapperを使用していましたが,今回はUnityBootStrapperからPrismBootStrapperに製品とまったく同様のDIコンテナ登録ロジックで記述して置き換えました。
ということでテスト専用のプロジェクトでもPrismBootStrapperのニーズはあるかもしれません。(ユニットテスト中には画面の表示は必要がありませんから・・・)
確かに!それは考え付きませんでした!
ServiceLocator パターンで DI コンテナからインスタンスを取得(このサイトでは推奨していませんが…)している場合には結構良さそうですね!
アイデアを拝借するようで申し訳ありませんが、このエントリに追記させて頂こうと思います。
当方はViewModelが使用するModelやPrismのクラスなどは全てViewModelのDIの機能によるコンストラクタ注入で使用しておりServiceLocatorパターンは使用しておりません。(とある参考書によるとServiceLocatorパターンは「悪」的な記述も読みました・・・・・
実際の製品で
起動時に(大抵はModuleで)DIコンテナにViewModelが使用するModelやPrismのクラスなどを登録(Register)しています。
そしてユニットテストprjでも
この挙動をPrismBootStrapperを使用することで挙動を合わせることができました。
あくまで参考までに・・・
kasa883さん >
返信遅くなりました。
すいません、kasa883さんが ServiceLocator を使われていると言う意味で書いた訳ではなく、以前 ServiceLocator についてのエントリを書いた時に ServiceLocator を使用した場合の単体テストを簡単に書けないだろうか… と考えていた問題が解決できそうだったのでつい書いてしまいました…
DIで実装しているユニットテストでも DI コンテナが使用できた方が楽な場合がありそうなのは何となく分かるので参考にさせていただきます!
今回も参考になりました。
「大人の事情」でスタートアップがWinodos Formで各種の新規追加実装部分の別のWindowやTab内部がPrismを使用したWPFの「複合」ソリューションにて
起動シーケンスをPrismBootStrapperに置き換えました。PrismBootStrapperの設計指針は,起動のシーケンスが,標準のPrismApplicationと同じようになるように設計されているように感じました。(以前のBootStrapperは標準のPrismApplicationとは起動のシーケンスが100%互換ではなかったようなので)
今後の記事も楽しみにしています。
kasa883 さん >
いつもありがとうございます。
PrismBootStrapper は管理人自身で試していませんが、お役に立てたなら良かったです。
コメントを頂けると書いている事が間違えていない事の確認ができるので非常に助かります。
今後ともよろしくお願いします。