Where and how to reference composite MVP components?
- by Lea Hayes
I am learning about the MVP (Model-View-Presenter) Passive View flavour of MVC. I intend to expose events from view interfaces rather than using the observer pattern to remove explicit coupling with presenter.
Context: Windows Forms / Client-Side JavaScript.
I am led to believe that the MVP (or indeed MVC in general) pattern can be applied at various levels of a user interface ranging from the main "Window" to an embedded "Text Field". For instance, the model to the text field is probably just a string whereas the model to the "Window" contains application specific view state (like a persons name which resides within the contained text field).
Given a more complex scenario:
Documentation viewer which contains:
TOC navigation pane
Document view
Search pane
Since each of these 4 user interface items are complex and can be reused elsewhere it makes sense to design these using MVP.
Given that each of these user interface items comprises of 3 components; which component should be nested? where? who instantiates them?
Idea #1 - Embed View inside View from Parent View
public class DocumentationViewer : Form, IDocumentationViewerView {
public DocumentationViewer() {
...
// Unclear as to how model and presenter are injected...
TocPane = new TocPaneView();
}
protected ITocPaneView TocPane { get; private set; }
}
Idea #2 - Embed Presenter inside View from Parent View
public class DocumentationViewer : Form, IDocumentationViewerView {
public DocumentationViewer() {
...
// This doesn't seem like view logic...
var tocPaneModel = new TocPaneModel();
var tocPaneView = new TocPaneView();
TocPane = new TocPanePresenter(tocPaneModel, tocPaneView);
}
protected TocPanePresenter TocPane { get; private set; }
}
Idea #3 - Embed View inside View from Parent Presenter
public class DocumentationViewer : Form, IDocumentationViewerView {
...
// Part of IDocumentationViewerView:
public ITocPaneView TocPane { get; set; }
}
public class DocumentationViewerPresenter {
public DocumentationViewerPresenter(DocumentationViewerModel model, IDocumentationViewerView view) {
...
var tocPaneView = new TocPaneView();
var tocPaneModel = new TocPaneModel(model.Toc);
var tocPanePresenter = new TocPanePresenter(tocPaneModel, tocPaneView);
view.TocPane = tocPaneView;
}
}
Some better idea...