もりゃきに後は無い

Prismサンプルを読み解く 第一回(第01章)

 WPFでMVVMなアプリを使うには、どうもフレームワークを使わないと相当つらいらしい。というわけでPrismの話。

 一番有名なMVVMフレームワークであるPrismを使うことにして、 公式サンプル を読み解いていこうと思いました。

 記事中にも書いてますが、Prism 7系になって Bootstrapper の利用に警告が出るようになりましたが、無くなったりはしないようです。なので、サンプル01の再現方法と、Prism 7.* 版の書き方を記載しています。

前置き

 誰かの参考になるか?そんなの知らんがな。個人のメモ、広告取ってないんだから好きに書かせて貰います。こういう所で手を抜くと、後々痛い目に遭うからねぇ。

 Visual Studio で フレームワーク Prism が使える環境になってることが前提。

1.Bootstrapper and the Shell

 日本語訳は「基本的なブートストラッパーとシェルを作成する」by DeepL

 おかしいな、Prism 6 までは Bootstrapper だったが、 Prism 7 では Application クラスを継承した PrismApplication に記述すると読んだのだが? でも、該当記事に Prism 8 から復活する可能性もあるらしい事もあるし、まずはこれで行きます。

 リンクを貼ったブログ、とても参考になりますし、参考にして書いてます。

 プロジェクトを作って違和感、そう、Prism Blank Appとサンプルの構成が違う。どうやら、.NET Core WPF アプリでプロジェクトを作るようだ。

注:この変更や追加をやってもエラーが出て動きません!

プロジェクトを再現するために必要な変更ファイルと内容

  • BootstrapperShell.csproj

NuGet から Prism.Unity 参照を追加することで

  <ItemGroup>
    <PackageReference Include="Prism.Unity" Version="7.2.0.1422" />
  </ItemGroup>
  • MainWindow.xaml → Views/MainWindow.xaml
  • MainWindow.xaml.cs → Views/MainWindow.xaml.cs

 ディレクトリ移動して、xaml 書き換えて xaml.cs を見たら InitializeComponent() が参照できなかったので、ルートにある MainWindow を削除して、Views ディレクトリで新しく WPF ウィンドウ追加した方がよさそうです。

  • App.xaml
<Application ...
  StartupUri="MainWindow.xaml">

 の startupUri="~" を削除する。

 これがあると、既に亡き MainWIndow.xaml を呼んじゃうんですね。Bootstrap と Shell の動作確認なんだから、XAMLから直接開いちゃ意味がありませんでした。

  • App.xaml.cs

 class App に OnStartup メソッドに追加

protected override void OnStartup(StartupEventArgs e)
{
  base.OnStartup(e);

  var bootstrapper = new Bootstrapper();
  bootstrapper.Run();
}

プロジェクトを再現するために必要な追加ファイルと内容

Bootstrapper.cs

 UnityBootstrapper を継承した Bootstrapper クラス作成

  • Using で Unity と Prism.Unity を宣言
using Unity;
using Prism.Unity;
  • CreateShell を override、base.CreateShell を呼ばず Container.Resolve を使う
    protected override DependencyObject CreateShell()
    {
        return Container.Resolve<MainWindow>();
    }
  • InitializeShell を override
	protected override DependencyObject CreateShell()
	{
		return Container.Resolve<MainWindow>();
	}

…あー本当だ、旧形式って警告が出る。

Warning

 とりあえず、この警告出てるのが Bootstrapper、そしてここで言う MainWindow が Shell に当たるのかな?

プロジェクトを Prism 7.* に対応する方法

 さて、ここで問題の警告を解消するにはどうすればいいか。そもそも解消する必要があるのか。

‘UnityBootstrapper’ は旧形式です (‘It is recommended to use the new PrismApplicaion as the app’s base class. This will require updating the App.xaml and App.xaml.cs files.')

 警告をコピペするために検索をかけたところ UnityBootstarpper is obsolote という Issue が引っかかりました。そして、このIssueに載ってる警告文との差違があります。「The Bootstrapper may be removed in a future release」この一文が消えてるんですね。「なくなりません(The bootstrapper isn’t going away.)」とリプもついてますね。

 BootStrapper を使わないということは、App.xaml へのコードビハインドになるということで、無くしたら都合が悪いということでしょうかね?

 一応、Prism 7での書き方が書いてある Getting started with Prism 7.0 を眺めてみますが、どうやら

  • App.xaml の StartupUriを置き換える
  • すべてのApplication要素に “prism:Prism “を追加
  • App.xaml.csのベースクラスを Application から PrismApplication に変更
  • using Prism.Unity; を追加
  • 最後にコードをクラスに貼り付け

 などの手順が書かれていますが…うん、動かない。バリバリにエラー出まくってくる。解決の目処がつかない。

 やむなく検索したら、Stack Overflow の How to implement the new PrismApplication to replace the Bootstrapper class に回答がありました。この記事と全く同じ事をやってる人がいたんですね。心強い。

 Viewsディレクトリに MainWindow.xaml を作り直したときはこうなります。

App.xaml

<unity:PrismApplication
  x:Class="BootstrapperShell.App"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:BootstrapperShell"
  xmlns:unity="http://prismlibrary.com/" />

App.xaml.cs

using System.Windows;
using Prism.Ioc;

namespace BootstrapperShell
{
  /// <summary>
  /// Interaction logic for App.xaml
  /// </summary>
  public partial class App
  {
    protected override Window CreateShell()
    {
      return Container.Resolve<Views.MainWindow>();
    }

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
    }
  }
}

 結論として、Bootstrapper を止める「必要」はないです。その上で「やるならばこうする」という内容でした。

 疲れた…何回分か一気に進めるつもりだったけど、無理だった。