コンポジション コンテナーをクエリする正当な理由は何ですか (デバッグと浮気以外)。実際のアプリケーション シナリオで、GetExports または GetExportedValues を使用する必要があるのはなぜですか? 追加のクラスを必要としないこと以外に、 import または importmany を使用する利点は何ですか?
2 に答える
私が知っている3つの理由があります:
不可抗力
一部のサードパーティ コード (制御できないコード) は、リフレクションを介して名前でクラスをインスタンス化します。これらのクラスは、コンストラクターで構成自体を処理する必要があります。
段階的なリファクタリング
DI を考慮せずに記述された既存の大規模なコード ベースが既にあるとします。依存性注入を使用するように徐々にリファクタリングしたいと考えています。
ランダムなクラスを選択して、依存性注入を使用するように変更するとします。通常、注入された依存性を受け取る代わりに、そのクラスをインスタンス化するクラスも変更する必要があることがわかります。それを修正する場合は、それらのクラスをインスタンス化するクラスなども変更する必要があります。
1 回のリファクタリングでコード ベース全体をすぐに変更しなければならないカスケードを回避するには、余分なコンポジション ルートを一時的に挿入すると便利なことがよくあります。
DIなしでハッピー
コントロールの反転なしで満足できるコード ベースが既にあり、1 つ以上の拡張ポイントを追加したいだけです。あるいは、依存性注入の代わりに Service Locator パターンを既に使用しているかもしれません。
通常、たとえば、1つのエクスポートのみを動的にロードする必要がある場合。たとえば、一部の入力に動的に依存します。
受信クラスにハードコードされているインポートが機能しないシナリオはたくさんあります。
一例は寿命です。GetExport / GetExportedValueを使用すると、データベースリポジトリを要求し、オブジェクトの有効期間外に破棄できます。これは、リポジトリが必要な場合と不要な場合があり、必要な場合はクラス全体を削除せずにリポジトリを削除する必要がある場合に便利です;)
次に、私がよく使用するサービスタイプのシナリオがあります。私のサーバーアプリには、開始するまで初期化されないサービスがあります-これは明らかにインポートが機能しないことを意味し、サービスの開始ではなく、サービスの作成時にオブジェクト構造全体を作成します;)これには正当な理由があります-たとえば、構成特定のマシンで開始するサービスを決定する可能性があり、私のサービスの一部はメモリを大量に消費するため(開始時に1ギガバイトまたは2つまたは10のキャッシュデータをプルする)、開始されていない場合は...存在しない方がよい。