Life is Really Short, Have Your Life!!

ござ先輩の主に技術的なメモ

Prism8のContainerLocatorへの対応

日本でWPFのPrismやってるの100人いるかどうかじゃないかな。なんでWindowsのデスクトップアプリなんか作ったんだろう。

Prism8が2020年の10月頃にリリースされ、破壊的変更が入った。ServiceLocatorがなくなってContainerLocatorに変わりました。それだけ言われてもどこを変えていいかわかんねーよって感じですけど、この2点を変えたら動いたので、共有。

RegisterTypes

Locatorなるものが管理するViewが一括で登録されるのがRegisterTypes。そういうものらしい。 Prism8になってIContainerRegistryからGetContainerメソッドがなくなったので、削除するだけでビルドが通った。

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            this.GetType().GetTypeInfo().Assembly
             .DefinedTypes
             .Where(t => t.Namespace?.EndsWith(".Views", System.StringComparison.Ordinal) ?? false)
             .ToList().ForEach(t => {
                //containerRegistry.GetContainer().RegisterTypeForNavigation(t.AsType(), t.Name);
                 containerRegistry.RegisterForNavigation(t.AsType(), t.Name);
             });
       }

RegionManager

ビルドは通ったけど、実行時例外(ぬるぽ)は別問題だよね。

Prismで画面遷移する時、GetRegionManager().RequestNavigate("ContentPage", nameof(HogePage));って書いている。ContentPageMainWindow.xamlに書いたこのコードに呼応してる。RegionNameだね。こうすることで、ヘッダー・フッターは固定でコンテンツだけ差し替えることが簡単にできる。便利まーん。

        <ContentControl prism:RegionManager.RegionName="ContentPage"  />

GetRegionManager()ではIRegionManagerインスタンスServiceLocatorから取得していたが、Prism8になってこのクラスのインスタンスはDIされなくなった。なので、こういうコードを書いたら動いた。

 protected IRegionManager GetRegionManager()
        {
            return ContainerLocator.Container.Resolve<IRegionManager>();
            //return ServiceLocator.Current.GetInstance<IRegionManager>();
        }

VIewModelの初期化時にRegionManagerを渡すことも出来るっぽい。IDialogServiceを使う時に、ViewModelのコンストラクタにインスタンスをDIするのと同じイメージ。以下のリンクは、IDialogServiceの使い方。Prism8になると、InteractionRequestは使えない。気をつけて。

prismlibrary.com

クライアントサイドのプログラム、なんとな〜く文脈をつかんでノリで書いたら動くことが多い。あはは。