1. ホーム
  2. wpf

[解決済み] ViewModelLocatorとは何ですか?また、DataTemplatesと比較した場合の長所と短所は何ですか?

2022-05-18 02:57:43

質問

ViewModelLocator とは何か、どのように機能するのか、DataTemplates と比較して、それを使用することの長所と短所を簡単にまとめてくれる人はいますか?

私はGoogleで情報を見つけようとしましたが、それの多くの異なる実装とそれが何であるか、それを使用することの長所/短所に関する明確なリストがないようです。

どのように解決するのですか?

導入

MVVM では、通常、View はビューモデルを 依存性注入 (DI) コンテナから解決することによって ViewModel を見つけさせることです。これは、コンテナがViewクラスのインスタンスを提供(解決)するように要求されたときに自動的に発生します。コンテナは を注入します。 を注入し、ViewModel のパラメータを受け入れる View のコンストラクタを呼び出すことで、View に ViewModel を注入します。このスキームは 制御の反転 (IoC) と呼ばれます。

DI のメリット

ここでの主な利点は、コンテナを構成することができることです。 を実行時に設定できることです。 を設定できることです。これにより、アプリケーションが実際に実行されるときには使用する型 (Views と ViewModels) を解決するように指示し、アプリケーションのユニット テストを実行するときには別の方法で指示することで、より高いテスト容易性を実現できます。後者の場合、アプリケーションには UI がありません (アプリケーションは実行されず、テストだけが実行されます) ので、コンテナは モック を、アプリケーションの実行時に使用される "normal" タイプの代わりに解決します。

DIに起因する問題

これまで、DIのアプローチでは、アプリケーションコンポーネントの作成に抽象化レイヤーを追加することで、アプリケーションのテスト容易性を高めることができることを見てきました。このアプローチには1つ問題があります。 ビジュアルデザイナーと相性が悪い。 Microsoft Expression Blendのようなビジュアルデザイナーとは相性が悪いのです。

問題は、通常のアプリケーションの実行とユニットテストの実行の両方において、誰かが をセットアップする必要があります。 を設定し、さらに、誰かが を尋ねます。 さらに、ViewModels を View に注入できるように、コンテナが View を解決するよう、 コンテナに依頼する必要があります。

しかし を実行する私たちのコードはありません。 . デザイナーはリフレクションを使用して私たちのViewsのインスタンスを作成しようとします。

  • View のコンストラクタが ViewModel のインスタンスを必要とする場合、デザイナーは View を全くインスタンス化することができず、何らかの制御された方法でエラーになります。
  • View がパラメータなしのコンストラクタを持つ場合、View はインスタンス化されますが、その DataContextnull であるため、デザイナーに "empty" というビューが表示され、これはあまり便利ではありません。

ViewModelLocator の入力

ViewModelLocator は、このように使用される追加の抽象化です。

  • View 自身が、ViewModelLocator をその リソース の一部としてインスタンス化し、その DataContext をロケータの ViewModel プロパティにデータ転送します。
  • ロケータはどういうわけか デザインモードであるかどうかを検出する
  • デザインモードでない場合、ロケータは上記で説明したようにDIコンテナから解決したViewModelを返します。
  • 設計モードの場合、ロケーターは独自のロジックを使用して固定された "ダミー" ViewModel を返します (設計時にはコンテナーは存在しないことを思い出してください!); この ViewModel には通常、ダミー データが事前に入力されます。

もちろん、これは、View が最初にパラメータなしのコンストラクタを持たなければならないことを意味します (さもなければ、デザイナーはそれをインスタンス化することができません)。

概要

ViewModelLocator は、MVVM アプリケーションで DI の利点を維持しながら、コードがビジュアルデザイナーとうまく連携できるようにするためのイディオムです。これは、アプリケーションのブレンド性(Expression Blendを参照)と呼ばれることもあります。

上記を理解した後、実用的な例をご覧ください。 ここで .

最後に、データテンプレートの使用は ViewModelLocator の代替ではなく、UI の一部に明示的な View/ViewModel のペアを使用するための代替となります。しばしば、ViewModel のために View を定義する必要がないことに気づくかもしれませんが、それは代わりにデータテンプレートを使うことができるからです。