SyntaxHighlighter

2020-09-28

PrismでDIコンテナを使用するRegister vs RegisterInstance vs RegisterSingleton

Prism 7以降に、サービスを注入する際に、Register, RegisterSingleton, RegisterInstance三つのメソッドが使えます。それぞれを使用する場面について、ちょっとした解説を書き残します。

実際にサービスを登録する場合、そのサービスを使用する場面によって、異なるサービスを使用するべきと言われていますが、次のように大まかに分けています:

  • Register 該当Interfaceが注入された場合、DIコンテナが自動的に新しいインスタンスを生成し、終わったときにインスタンスを廃棄する。
  • RegisterSingleton 全部の注入には同じインスタンスで対応する。
  • RegisterInstance 主にRegisterSingletonと同じだが、生成されるInstanceは自分で管理する場合使用。

では、どれを使うほうか正解ですか?

まぁ、ほとんどなサービスはSingletonとして登録されます。ViewModelはそれらのサービスによって通信できるようにするためです。例えば、EventAggregatorサービスで、あなたが持つあるViewModelからEventを発行する際に、他の何かはそのことを知らせたいですが、それは同じインスタンスのサブスクリプションを発行者サービスとして登録している場合受け取ることができます。とはいえ、WCFクライアントは、同じシングルトンを使用する必要はありません。なぜならば、その処理はサーバー側が処理すべきなのです。

場合によっては、インスタンスを登録することは嫌がります。特に登録(register)と逆解析(resolve)が混在している場合。インスタンスを作成する際にそのインスタンスの依頼先をすべて確保する場合も。(だからResolveを呼び出す。その呼び出す自体がやや気に障るが。)

ひとつのメソッドですべての必要項目を全部登録してしまえば問題は減りますが、複数の交互依頼モジュールがある場合にはちょっと頭痛いです。

訳者注記

最近のプロジェクトでDBのアクセスサービスに、Singletonの登録にはちょっと問題あると気付きました。EntityFrameworkのDbContextを利用していますが、すべての画面が同じDbContextを登録した場合、DB側に更新がある場合、リアルタイムにReloadができません。渋々にSingletonを解除して、画面ごとに新しいDbContextを使うことにしたら、キレイに解決しました。ネットで検索したら、DbContextは長時間メモリに滞在するようには良い影響はしないようです。とりあえずEntityFrameworkのDbContextはSingleton登録しないようにする方が良いです。あるいは必要の場合自分でインスタンスを管理する方が良いかもしれません。

人気の投稿