2012-12-20 11 views
6

windsorコンテナを使用して以下のMVPデザイン(winforms用)を作成するときに巡回依存性の問題に直面しています。依存性注入のためにWindsor castleを使用したMVPパターンでの循環参照の問題

私のプレゼンターがビューとモデルによって異なります。

ConcretePresenter(IView view, IModel model) 
{ 
    this.view = view; 
    this.model = model; 
} 

私の見解は、プレゼンターによって異なります

ConcreteView(ConcretePresenter presenter) 
{ 
    //actual requirement that the presenter use the current instance of the view and a model object 
    //new presenter(this, new model()) 
    this.presenter = presenter; 
} 

私は(別の組成物のルートクラスで)ウィンザー城を使用して、すべてのコンポーネントを登録しています以下のようになります。

IWindsorContainer container; 
container = new WindsorContainer(); 
container.Register(Component.For<ConcretePresenter>().ImplementedBy<ConcretePresenter>()); 
container.Register(Component.For<IModel>().ImplementedBy<ConcreteModel>());      
container.Register(Component.For<IView>().ImplementedBy<ConcreteView>()); 

ビューを解決すると、考えられる解決策は、コンストラクタインジェクションをビューから削除し、プレゼンタを個別に解決することです。 しかし、これは私がやっていない2つの場所でコンテナを使用し、おそらく間違っています。

ConcreteView() 
{ 
    container.Resolve<ConcretePresenter>(); //resolving at 2 different points  
} 

これに対する解決策はありますか? MVP自体に何か間違っているのですか?

+0

重複:http://stackoverflow.com/questions/1783124/castle-ioc-resolving-circular-references – Roubachof

答えて

4

この問題にはいくつかの解決策がありますが、それらはすべて、プレゼンターまたはビューのいずれかをコンストラクターの依存関係から削除することによって依存関係のサイクルを中断します。

最も簡単な解決策は、プレゼンターのプロパティとしてビューを導入することにより、次のようになります。これの

// Presenter 
ConcretePresenter(IModel model) 
{ 
    this.model = model; 
} 

public IView View { get; set; } 

// View 
ConcreteView(ConcretePresenter presenter) 
{ 
    this.presenter = presenter; 
    this.presenter.View = this; 
} 

欠点は、それがビュー内に注入されるように、各プレゼンターを設定する必要があるということですので、あなたも移動することができます基本クラスには、この:

// View 
ConcreteView(ConcretePresenter presenter) : base(presenter) 
{ 
} 

BaseView(IPresenter presenter) 
{ 
    Contract.Requires(presenter != null); 
    presenter.View = this; 
    this.Presenter = presenter; 
} 

別のオプションは、ビューにプレゼンターの工場を注入し、そこからそれを要求することです:

// View 
ConcreteView(IPresenterFactory factory) 
{ 
    this.presenter = factory.CreatePresenterFor(this); 
} 

欠点は、このコンストラクタが工場を呼び出すことです。これは最もクリーンではなく、管理しやすいものです。

+0

私はあなたの提案したように最初のオプションを使用して、それは私のために動作します。 –

+0

私はこれが貧弱だと思いますDi原因コンポジットルートから別のポイントに注入を移動します。 – Kenji

0

プレゼンターをインスタンス化するためのファクトリを作成します。あなたのビュー(WinForm)はコンストラクタでファクトリを使用します。おそらく型付きファクトリファシリティを使用することができます。つまり、プレゼンタファクトリのインターフェイスを定義し、そのファシリティに残りの処理をさせるだけです。

+0

サンプルコードを入手することは可能でしょうか? –

関連する問題