2012-12-20 29 views
6

Tôi đang đối mặt với một vấn đề phụ thuộc cyclic khi tạo thiết kế MVP sau đây (cho winforms) bằng cách sử dụng container windsor.Vấn đề tham chiếu tuần hoàn trong mẫu MVP bằng cách sử dụng Windsor castle cho Dependency injection

người dẫn chương trình của tôi phụ thuộc vào quan điểm và mô hình:

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

Quan điểm của tôi phụ thuộc vào người dẫn chương trình:

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; 
} 

Tôi đăng ký tất cả các thành phần sử dụng Windsor lâu đài (trong một lớp thành phần gốc riêng biệt) như sau:

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>()); 

Giải quyết chế độ xem sẽ trả về vấn đề tái chế theo chu kỳ vấn đề về ference:

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

Một giải pháp có thể là loại bỏ việc xây dựng phun khỏi chế độ xem và giải quyết riêng người trình bày. Nhưng điều này khiến tôi sử dụng vùng chứa ở hai nơi mà tôi không muốn làm và có thể là sai.

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

Có giải pháp nào tốt hơn cho điều này không. Tôi có làm gì sai trong MVP không?

+0

có thể trùng lặp: http://stackoverflow.com/questions/1783124/castle-ioc-resolving-circular-references – Roubachof

Trả lời

4

Có một số giải pháp cho vấn đề này, nhưng tất cả chúng đều phá vỡ chu trình phụ thuộc bằng cách loại bỏ trình bày hoặc khung nhìn từ phụ thuộc hàm tạo.

Giải pháp đơn giản nhất sẽ là bằng cách giới thiệu quan điểm như tài sản trên người dẫn chương trình:

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

public IView View { get; set; } 

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

Nhược điểm của việc này là bạn cần phải cấu hình mỗi người dẫn chương trình khi nó được tiêm vào xem, do đó bạn cũng có thể di chuyển này đến một cơ sở lớp:

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

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

lựa chọn khác là tiêm một nhà máy người dẫn chương trình vào xem và yêu cầu nó từ đó:

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

Nhược điểm là nhà xây dựng này gọi một nhà máy, đó không phải là điều sạch nhất để làm, nhưng có thể quản lý được.

+0

Tôi đã sử dụng tùy chọn đầu tiên theo đề xuất của bạn và nó hoạt động cho tôi. –

+0

Tôi nghĩ rằng điều này là nghèo Di gây ra Di chuyển tiêm từ gốc Composite đến một điểm khác. – Kenji

0

Tạo một nhà máy để khởi tạo diễn giả của bạn. Quan điểm của bạn (WinForm) sẽ sử dụng nhà máy trong constuctor. Bạn có thể sử dụng cơ sở nhà máy được đánh máy - nghĩa là bạn chỉ phải xác định giao diện cho nhà máy trình bày và để cho cơ sở làm phần còn lại.

+0

bạn có thể lấy mã mẫu không? –

Các vấn đề liên quan