10

デザイン可能な .NET コンポーネントを作成するときは、既定のコンストラクターを指定する必要があります。IComponentのドキュメントから:

コンポーネントになるには、クラスは IComponent インターフェイスを実装し、パラメーターを必要としないか、タイプ IContainer の単一のパラメーターを必要とする基本的なコンストラクターを提供する必要があります。

これにより、コンストラクター引数を介して依存性注入を行うことができなくなります。(追加のコンストラクターを提供することもできますが、デザイナーはそれらを無視します)。

  • サービスロケーター

    依存関係の挿入を使用しないでください。代わりに、サービス ロケーター パターンを使用して依存関係を取得してください。これは、IComponent.Site. GetServiceはそのためのものです。必要な依存関係で構成できる再利用可能な ISite 実装 (ConfigurableServiceLocator?) を作成できると思います。しかし、これはデザイナーのコンテキストではどのように機能するのでしょうか?

  • プロパティによる依存性注入

    プロパティを介して依存関係を注入します。デザイナーでコンポーネントを表示するために必要な場合は、既定のインスタンスを提供します。注入する必要があるプロパティを文書化します。

  • Initialize メソッドで依存関係を注入する

    これはプロパティを介した注入によく似ていますが、注入する必要がある依存関係のリストを 1 か所に保持します。このようにして、必要な依存関係のリストが暗黙的に文書化され、コンパイラーはリストが変更されたときにエラーを支援します。

ここでベストプラクティスは何ですか?どのようにしますか?


edit : コンポーネント全般に関する質問をするつもりだったので、「(例: WinForms UserControl)」を削除しました。コンポーネントはすべて制御の反転に関するものなので ( UMLv2 仕様のセクション 8.3.1 を参照)、「サービスを注入してはならない」というのは良い答えではないと思います。


編集2:最終的にマークの答えを「得る」には、WPFとMVVMパターンをいじる必要がありました。ビジュアル コントロールは確かに特殊なケースであることがわかりました。デザイナー サーフェイスでの非ビジュアル コンポーネントの使用に関しては、.NET コンポーネント モデルは基本的に依存性注入と互換性がないと思います。代わりに、サービス ロケーター パターンを中心に設計されているようです。おそらく、これは、.NET 4.0 でSystem.ComponentModel.Composition名前空間に追加されたインフラストラクチャで変わり始めるでしょう。

4

1 に答える 1

7

この同じ質問は、私が間違った方法で考えていることに気付くまで、長い間私を悩ませていました. AFAIR、IComponent実装を作成する唯一の理由は、設計時の機能を提供することです.IComponent実装の実行時効果はありません。

当然のことながら、これは、ほとんどの場合、設計時の機能を実装するためにコンポーネントを作成する必要があることを意味します。特にコントロールの場合、これは、特定の方法で動作するようにコンポーネントを構成できることを意味します。これは、コンポーネントが実際にどのように動作するか、またはコンポーネントが表示するデータとはまったく異なる問題であることを認識することが非常に重要です。設計時に動作するべきではなく、データを含むべきでもありません。

このように、コンストラクターに対する制約は、設計を再考するように指示するため、実際には祝福です。コントロールは、特定の方法でデータを表示および操作するよりも、データ ソースに依存しないソフトウェアです。そのデータが特定のインターフェイスなどに準拠している限り、コントロールは満足しています。そのデータがどのように到着するかは、コントロールには関係ありません。Control にデータのロード方法と変更方法を制御させるのはエラーになります。

WPF では、これは Windows フォームよりも明らかに明確です。特定のコントロールに DataContext を与え、コントロールのプロパティをその DataContext のメンバーにバインドします。DataContext (任意のオブジェクトである可能性があります) は、Control の外部から発生します。それは責任またはプレゼンテーション層です。

Windows フォームでは、データ コンテキストをコントロールに割り当てることで、同じことを行うことができます。基本的に、これはプロパティ インジェクションです。サービスをインジェクトしてはならないことに注意してください。データを注入する必要があります。

要約すると、私はあなたの提案のどちらにも行きません。代わりに、Control にデータを割り当てることができる 1 つ以上のプロパティを Control に持たせ、databinding を使用してこのデータにバインドします。コントロールの実装内で、データがない状況を処理する準備をしてください。これは、デザイン時にコントロールが VS によってホストされるたびに発生します。Null Object パターンは、このような回復力を実装するのに非常に役立ちます。

次に、コントローラーからデータ コンテキストを設定します。これが MVC の方法です。コントロールはビューですが、モデルをインスタンス化してビューに割り当てることができる別のコントローラーが必要です。

于 2009-07-02T19:40:34.080 に答える