私は MVP パターンを使用している Visual Studio .NET 4.0 で Windows アプリケーションを開発しており、アプリケーション全体で依存性注入の原則を学習して適用しようとしています。しかし、特定の状況に対処する最善の方法を理解するのに苦労しています. 長い説明を前もってお詫びしますが、それ以外の方法で十分に具体的に説明できるかどうかはわかりません.
このアプリケーションは、さまざまな種類の記録に対応する汎用の記録管理アプリであり、相互に関連するものもあれば、他の記録とは無関係のものもあります。私たちが扱うそれぞれの異なるレコードタイプは、アプリケーションの個別の「機能」を構成します。したがって、アプリケーションの起動画面は基本的に、ナビゲートしたい機能を選択できるスイッチボードです。
選択すると、その機能のウィンドウ (ビュー) が開き、このウィンドウからその機能に関するさまざまな操作を実行できます。ほとんどの機能 (顧客、注文など) には、ユーザーが実行できる一般的な操作 (新しいレコードの作成、既存のレコードを開く、変更の保存、印刷など) があります。ただし、その 1 つの機能に固有の操作を持つものもあります (注文機能に固有の検証操作など)。私の問題は、各機能内で操作を実行する方法を理解することにあります。
私は MVP を使用しているため、機能ウィンドウには、ユーザーがその機能の操作を開始したときに応答するプレゼンターがあります。しかし、私は単一の責任の原則に従いたいので、プレゼンターが神のクラスになり、実際にレコードの作成、保存、印刷などの方法を知ってほしくないので、私の考えは、各操作を処理するために別々のクラスを定義することでした。 .Create() メソッドを使用した ICreateOrders 実装、.Save() メソッドを使用した ISaveOrders 実装などがあります。それらに名前を付けるために、実際にリクエストを解決するため、「リゾルバー」と呼びます。その操作が行われるようにします。これらの一般的なリゾルバーのいくつかは、おそらく基本実装 (基本的な FeatureSave クラスなど) を持っているでしょう。ただし、必要に応じて、各機能に特定の実装を含めることができる必要があります。このアプローチには、いくつかの疑問が生じます。
まず、これらのアクションを、その機能のウィンドウだけでなく、アプリ内の他の場所から開始できるようにしたいと考えています。たとえば、注文機能ウィンドウ内からのみ注文レコードを開くことができるのではなく、顧客機能から「注文の表示」を選択して、その顧客の注文レコードを開いて自動的に表示できるようにしたいと考えています。そして、コードの再利用を実現するために、アプリ内のどこからリクエストが開始されたかに関係なく、同じ IOpenOrders 実装を使用してジョブを実行したいと考えています。そのため、必要なリゾルバーを [注文] ウィンドウのプレゼンターに埋め込むだけでは、選択肢のようには思えません。
そこで、Feature オブジェクトのコレクションを保持する FeatureService クラスを作成することを考えました。アプリの起動時に、ログインしているユーザーに有効なすべての機能のリストをデータベースから取得し、そのリストを繰り返し処理して、それぞれの Feature オブジェクトを作成し、FeatureService のコレクションに追加します。次に、ある機能の操作を別の機能から開始する必要がある場合は、FeatureService オブジェクトをソース クラスに挿入し、そこからターゲット機能を取得し、それを使用して操作を実行するだけで実現できます。しかし、Feature クラスを God クラスにしたくないので、これは単に、個々のリゾルバーをすべて Orders プレゼンターから Feature クラスに移動することになります。
しかし、これを実現するには、ユーザーがそれらの操作を実行するかどうかを知らずに、Feature オブジェクトに必要な可能性のあるすべてのリゾルバーを挿入する必要があります。より複雑な機能の一部では、これは 20 または 30 の異なるリゾルバーが注入される可能性があり、これは確かにコンストラクター注入の悪用のようです。これにより、Feature オブジェクトが God クラスになることはありませんが、注入されたリゾルバーに各操作を渡すだけなので、これは間違っているようです。オブジェクトがこのように「神の調整者」になる場合、これは正しい使用法ですか?
私の他の質問は、これらのオブジェクトのボリュームについてです。顧客によっては、50 以上の個別の機能を利用できる場合があります (時間の経過とともにさらに多くの機能が追加されることは間違いありません)。したがって、起動時にこれらの Feature オブジェクトを作成し、コンテナーがこれらすべてのリゾルバー依存関係をそれぞれに注入しているため、それらの機能の一部にアクセスするかどうかに関係なく、何百ものオブジェクト (たとえば、機能ごとに 40 個の機能 X 20 個のリゾルバー) を作成しています。いいえ。典型的なユーザー セッションでは、おそらくいくつかの機能を使用するだけなので、このように起動時に非常に多くのオブジェクトを作成するのは無駄に思えます。あきらめて、Feature オブジェクトに内部的に ServiceLocation を実行させてリゾルバーを取得することもできますが、より良い方法があればそれを使用したいと思います。
ここからどこへ行けばいいのかわかりません。これに関する例と情報を探して見つけようとしましたが、何を検索すればよいかを知るのに十分な知識があるかどうかさえわかりません。誰でも提供できるガイダンスや洞察は大歓迎です。