Prism 7 系で色々仕様変更がありましたが、その中でも大きな変更のうちの 1 つが DI コンテナにクラスを登録する処理の変更です。今までは各 DI コンテナのクラスを直接触っていましたが IContainerRegistry インターフェースというインターフェースが Prism から提供されて、それに対してクラスを登録するという形になりました。
IContainerRegistry は、各々の DI コンテナごとに実装があって、その先で DI コンテナの個別の API を呼び出しています。利用者からしたら DI コンテナに何を使っていたとしても Prism の提供する箱庭の中にいる限りは同じコードでよくなるというようになっています。
IContaienrRegistry インターフェースには以下のようなメソッドが定義されています。
- RegisterInstance
- RegisterSingleton
- Register
- IsRegistered
登録系機能オンリーって感じですね。
そのほかに Prism.Wpf や Prism.Forms で画面遷移用にページを追加するための RegisterForNavigation などの拡張メソッドが定義されています。
DI コンテナ固有の API を呼びたい
ということで、Prism を基本的に使う上で必要な処理が、どの DI コンテナを使っていたとしても同じように書けるように改善されています。 ところで、DI コンテナ固有のパワフルな機能を呼びたいとしたらどうするの?という疑問が出てきますが、これも一応逃げ道が用意されています。
IContainerRegistry インターフェースには、各 DI コンテナ固有の実装が入っているパッケージ(Prism.Unity.Forms や Prism.DryIoc.Forms や Prism.Unity.Wpf など) に GetContainer という拡張メソッドが定義されています。
これを使うと各 DI コンテナの生のインスタンスが取れるので、これを使うことで DI コンテナ固有の機能 (AOP や Resolve 時の引数の解決に独自処理を入れたりなど) を使うことができるようになっています。
ということで、これを使うと App クラスの RegisterTypes あたりでこんな風に書けるようになります。
protectedoverridevoid RegisterTypes(IContainerRegistry containerRegistry) { // コンテナのインスタンスを取得する IUnityContainer container = containerRegistry.GetContainer(); // using Prism.Unity; をすると使えるようになる// コンテナ固有の機能にアクセス可能(この例では Unity の機能でコンストラクタに固定値を渡すようにしてる container.RegisterType<Sample>(new InjectionConstructor(10)); }
まとめ
Prism の用意してくれた IContainerRegistry という箱庭でおさまる場合はいいですけど、そうじゃない場合は今回紹介した GetContainer というメソッドを使ってお使いの DI コンテナ固有の機能を使って、よりパワフルな機能を使って便利に開発するのもいいかなって思います。
それでは、良い Prism Life を。