2012-12-20 38 views
6

Aşağıdaki MVP tasarımını oluştururken (winforms için) windsor kabı kullanarak döngüsel bağımlılık sorunu yaşıyorum.Bağımlılık enjeksiyonu için Windsor kalesini kullanan MVP düzenindeki döngüsel başvuru sorunu

Benim sunum görünümü ve modeline bağlıdır:

Bence sunucu bağlıdır
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; 
} 

Ben (ayrı bir kompozisyon kök sınıfında) Windsor Kalesi kullanarak tüm bileşenler kayıt am aşağıdaki şekilde gösterildiği gibi:

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>()); 
Görünümün Çözümlenmesi döngüsel yeniden sorununu gündeme getirir fark olmamas sorunu:

container.Resolve<ConcreteView>(); //doesn't resolve because of cyclic dependency 

Muhtemel bir çözüm görünümünden yapıcı enjeksiyon çıkarın ve ayrı sunum çözmek olacak. Ancak bu, konteynırı, yapmak istemediğim ve muhtemelen yanlış olan iki yerde kullanmama neden oluyor.

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

Buna daha iyi bir çözüm var mı. MVP'nin kendisinde yanlış bir şey mi yapıyorum?

+0

olası yinelenen: http://stackoverflow.com/questions/1783124/castle-ioc-resolving-circular-references – Roubachof

cevap

4

Bu soruna çeşitli çözümler vardır, ancak bunların tümü, sunucu veya çıkarıcı bağımlılığı görünümünden birini kaldırarak bağımlılık döngüsünü bozar.

kolay çözüm sunucu üzerinde mülkiyet olarak görünümü tanıtarak olacaktır: Bunun

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

public IView View { get; set; } 

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

Downside o görünüme enjekte edildiği gibi her sunum yapılandırmanız gerekir ki, bu yüzden de hareket edebilir Bu bir üsse sınıfı:

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

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

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

Diğer bir seçenek görünüm içine bir sunum fabrikası enjekte ve oradan talep etmektir

Dezavantajı, bu kurucunun, yapılacak en temiz şey değil, yönetilebilir bir fabrika olarak adlandırılmasıdır.

+0

Sizin tarafınızdan önerilen ilk seçeneği kullandım ve benim için çalışıyor. –

+0

Bunun kötü olduğunu düşünüyorum. Dezenfeksiyonu Kompozit kökten başka bir noktaya taşıyın. – Kenji

0

Sunucunuzu oluşturmak için bir fabrika oluşturun. Görüşünüz (WinForm) fabrikayı kurucuda kullanacaktır. Muhtemelen Typed Factory Facility'i kullanabiliyordunuz - bu sadece sunum fabrikasının arayüzünü tanımlamanız ve tesisin geri kalanını yapmasına izin vermeniz anlamına gelir.

+0

Örnek kod almak mümkün olabilir mi? –

İlgili konular