1

Observerパターンを採用しようとしているアプリケーションを開発しています。基本的に、さまざまなコンポーネント (フォーム) をロードできる基本フォームがあります。

基本フォームは各コンポーネントを参照し、一部のコンポーネントは相互に参照します。

コンポーネントの 1 つが基本フォーム (おそらくメニューなどから) によって発生したイベントをリッスンするようにしたい場合、コンポーネントの基本フォームへの参照を追加する必要なしにこれを達成することはできないようです。これにより、「循環参照」が発生します。

参照されていないプロジェクトのイベントをリッスン/サブスクライブすることはできますか?

4

6 に答える 6

1

Microsoft は開発中の "Managed Extensibility Framework (MEF)" を持っています。MEF の概要から:

MEF は、ホスト アプリケーションがそれ自体を公開し、外部拡張機能を使用するための標準的な方法を提供します。拡張機能は、その性質上、さまざまなアプリケーション間で再利用できます。ただし、アプリケーション固有の方法で拡張機能を実装することはできます。拡張機能自体は相互に依存する可能性があり、MEF はそれらが正しい順序で接続されていることを確認します (これについては心配する必要はありません)。

MEF の概要とダウンロードは、http://www.codeplex.com/MEF/Wiki/View.aspx? title=Overview&referringTitle=Home にあります。

于 2008-12-14T22:51:00.607 に答える
1

これはさまざまな方法で解決できます。簡単な方法の 1 つは、基本フォームとさまざまなコンポーネントを認識する特別なクラスを用意することです。このクラスは、フォームとコンポーネントの作成を担当します。それらを認識しているため、イベント ハンドラーを適切なイベントにアタッチできます。基本的には、コンポーネントのイベント ハンドラー メソッドをベース フォームのイベントに "プラグイン" するだけです。

もう 1 つの方法は、メイン フォームによって実装されるイベントを持つインターフェイスを定義することです。コンポーネントには、コンストラクターでこのインターフェイスのインスタンスを渡すことができます。その後、イベント ハンドラーにアタッチできます。したがって、コンポーネントはインターフェースのみを認識し、基本フォームは認識しません。これは、「実装ではなく抽象化に依存する」という原則の適用です。この場合、基本フォームはインターフェイスを実装し、コンポーネントの知識を持ち、構築時に自分自身を渡します。したがって、依存関係は一方向です。

ただし、最終的な解決策は、 StructureMapなどの依存性注入コンテナーを使用することです。基本フォーム クラスをインターフェイスのデフォルトの実装者として登録する構成メソッドと、さまざまなコンポーネント クラスがあります。その後、StructureMap は必要に応じてクラスのインスタンスを作成し、インターフェイスをコンストラクターに自動的に挿入できます。

于 2008-12-14T22:33:02.937 に答える
1

フレームワークは、物事を接続するために使用されるインターフェースを定義する必要があります (イベントはインターフェースで定義できるため、イベントをインターフェースに昇格させることができることに注意してください)。「実装ではなく抽象化に依存する」というマイク・スコットのアドバイスは的を射ていますが、ここではもう少し強くなります。

または、リフレクションを介して情報を取得するために使用できる文字列を提供する INotifyPropertyChanged などのインターフェイスを使用できますが、これは非常に壊れやすい作業方法であり、最後の手段にする必要があります。

于 2008-12-14T23:33:36.747 に答える
0

イベントのクラスを使用してプロジェクトを作成するだけです。

public class BaseFormEventClass
{
    public EventHandler<EventArgs> BaseFormDidSomething;
}

次に、ベースフォームプロジェクトとコンポーネントプロジェクトの両方からこのプロジェクトを参照します。ベースフォームにイベントクラスのインスタンスを作成させ、ロードするすべてのコンポーネントにそれを渡します。

public class MyComponent
{
    public MyComponent(BaseFormEventClass eventClass)
    {
        eventClass.BaseFormDidSomething += this.EventClass_BaseFormDidSometing;
    }
    // ...
}

public class BaseForm
{
    private BaseFormEventClass eventClass = new BaseFormEventClass();

    private void LoadComponents()
    {
        MyComponent component1 = new MyComponent(this.eventClass);
    }

    private void RaiseBaseFormDidSomething()
    {
        EventHandler<EventArgs> handler = eventClass.BaseFormDidSomething;
        if (handler != null) handler(this, EventArgs.Empty);
    }
}
于 2008-12-18T10:01:55.573 に答える
0

Microsoft の Patterns and Practices Libraryにある EventBroker パターンを使用できます。

個人的には、オブジェクトが相互に参照しないアーキテクチャ (常に親子のシナリオ) を作成し、依存関係の問題を無視するのではなく対処することを好みます。

于 2008-12-14T22:25:38.273 に答える