I haven't worked much with MVC, however I have worked a lot with MVVM and here's my take on it:
Question
, Answer
, and User
are all data objects. Its OK for them to know of each other, but they should not be aware of anything outside of the data object layer, such as Views, Controllers, ViewModels, etc.
In an ideal world, your View only references the Models. They might know of the Controller, but they shouldn't have to reference it directly. The ViewModel only knows of other Models. The Controller knows about Models and ViewModels. It doesn't care about the View at all, even though it supplies the View with ViewModels or Models.
So your objects end up looking like this:
M odels come in two varieties: Models and ViewModels.
- Models are simple data objects that simply exist to hold data, and are generally a reflection of database data. They do not access the database or contain any sort of business logic that is unrelated to them.
- ViewModels are data objects that contain data that the View needs, not necessarily what the database needs. They can contain Models, although Models should not contain ViewModels.
C ontrollers contain your business logic. They control the data access calls, creating Models/ViewModels to pass to the View, advanced business logic such as permissions, etc. They basically control the entire code layer.
V iews are just used to give the users a user-friendly interface. They accept either a ViewModel or Model, and display it in some way that looks nice to the user.
So I think you have some minor violation of MVVM | MVPVM patterns due to linkage you're creating between the views. Neither pattern is all that verbose with respect to child windows though, so it's a bit of a murky area.
I think it's worth pointing out that the big advantage of MVPVM vs. MVVM is because of separating out business logic. The VM becomes a data container and the P handles logic plus DAL access. Bill Kratochvil's article on MVPVM was a very good read.
Bill makes a comment regarding child windows and re-use that I think is apt:
In cases where a Presenter can be reused across enterprise applications, it’s likely a module would be better suited for the task—that is, you could create a login module (project) that could be reused by all of your enterprise applications.
Which kind of reinforces that you're in murky territory with two child components.
Regardless of MVVM or MVPVM, I think you would need either
B-VM
and C-VM
when using MVVM
B-P
and C-P
and B-VM
and C-VM
when using MVPVM
because they are functionally separate from A. If they're not functionally separate, then why do they need their own Views?
I think the challenges you bring up with swapping ViewB and ViewC is because there is some blurring between object ownership and responsibilities. Which is really just another way of asking if B and C are functionally separate from A or not. If they are, then make them that way and if not, then don't set them up as independent.
For lightweight stuff without a lot of business logic that could be re-used, I think that MVPVM is more effort than it's worth with MVVM. That's clearly a generality, and the business logic of your application may lend itself to being expressed more elegantly with MVPVM. Based upon your question though, it sounds like MVVM may be sufficient for what you need.
Best Answer
Keep mapping implementation out of your controllers. Instead, call the thing responsible for mapping in your controller.
Of course, if your ViewModel is just a property or two, you can skip the mapper.
With a little luck, AutoMapper might help you map objects without writing custom mappers.
I wouldn't store mapping implementation in the ViewModels themselves. This gets awkward when one ViewModel can represent data from more than one source. It also mixes responsibilities a little too much for my tastes.