Switching out Views

Topics: CAB & Smart Client Software Factory
Aug 8, 2007 at 2:59 AM
Hello All,

Forgive me if this is a basic question, but I don't see how the WorkItem-Presenter-View pattern helps me switch out and use a different view (for example, if I want to use the same WorkItem to drive a WPF application and a Web application). The problem I have is that the WorkItem is creating the View using an explicit reference to the type of the view, for example (from the SCSF docs):

protected override void OnRunStarted()
{
base.OnRunStarted();
SummaryView view = this.Items.AddNew<SummaryView>();
workspace.Show(view);
}

It seems to me that this coupling of the WorkItem with the type of it's presentation layer prevents the kind of swapping out that CAB is supposed to enable. Am I missing something?

Regards,
Bryn Rhodes
Database Consulting Group LLC

Aug 8, 2007 at 4:55 AM

It seems to me that this coupling of the WorkItem with the type of it's presentation layer prevents the kind of swapping out that CAB is supposed to enable. Am I missing something?


I think what you're missing is in this line:


I don't see how the WorkItem-Presenter-View pattern helps me switch out and use a different view (for example, if I want to use the same WorkItem to drive a WPF application and a Web application).


WinForms, WPF and ASP.NET are such different technologies that this sort of "view swapping" is unrealistic at best. To use CAB with WPF, for instance, requires an add-in to CAB via the SCSFContrib project. Web forms... There's MonoRail (CAB hasn't even been used, to the best of my knowledge, for a web app; the two technologies are just far too different).

The "view swapping" that you can do with CAB is to swap view implementations. For instance, one version of a UserControl for another, each implementing the same interface. This is useful in certain applications where different sets of users may want access to the same data, just presented in different ways (thus the WorkItem can drive the Use Case, and a different concrete view could be used).

But the real power of the MVP pattern utilized in CAB is in Separation Of Concerns and testability. In practice, view swapping appears to be rare (it certainly has been in the application we're building).

This still doesn't answer the "how" part of your question though, as you speak to the concrete view type being referenced by the WorkItem. A couple solutions: (a) A factory pattern to provide the view or (b) dependency injection to supply the view. With configuration settings of some type you could setup the specific concrete view at runtime.

Aug 8, 2007 at 3:40 PM


WinForms, WPF and ASP.NET are such different technologies that this sort of "view swapping" is unrealistic at best. To use CAB with WPF, for instance, requires an add-in to CAB via the SCSFContrib project. Web forms... There's MonoRail (CAB hasn't even been used, to the best of my knowledge, for a web app; the two technologies are just far too different).


I wondered if that would be the case, but I can dream, can't I :)


The "view swapping" that you can do with CAB is to swap view implementations. For instance, one version of a UserControl for another, each implementing the same interface. This is useful in certain applications where different sets of users may want access to the same data, just presented in different ways (thus the WorkItem can drive the Use Case, and a different concrete view could be used).

But the real power of the MVP pattern utilized in CAB is in Separation Of Concerns and testability. In practice, view swapping appears to be rare (it certainly has been in the application we're building).

This still doesn't answer the "how" part of your question though, as you speak to the concrete view type being referenced by the WorkItem. A couple solutions: (a) A factory pattern to provide the view or (b) dependency injection to supply the view. With configuration settings of some type you could setup the specific concrete view at runtime.


Thanks for the reply, I'll try some of these solutions.

Regards,
Bryn Rhodes
Aug 8, 2007 at 9:41 PM
The app I am currently working on is a hybrid smart client / web client, with both winforms and asp.net views for some modules. What you are missing is that its not the WorkItem-View-Presenter that allows you to swap out views, but rather the Model-View-Presenter. As long as your view implements the model and your presenter is written in a way such that it only interacts with the model and not the view directly, then you will be able to reuse the model and presenter with another view.

As I understand it the WorkItem is mostly meant as a managed object container to drive a use case, so you really should not have much if any logic in the WorkItem other than what pertains to the views, items and ui extensions etc, for that use case. Take a look at web client software factory for an example of how to use object builder to inject your presenter into asp.net views.

A word of warning though, it can be a nightmare trying to reuse the presenter, depending on how you have coded things in the past. It may be a better solution just to reuse the model and make new presenters for asp.net views salvaging what code you can from your CAB presenters.
Aug 14, 2007 at 7:21 AM
Edited Aug 14, 2007 at 7:22 AM


sefstrat wrote:
As I understand it the WorkItem is mostly meant as a managed object container to drive a use case, so you really should not have much if any logic in the WorkItem other than what pertains to the views, items and ui extensions etc, for that use case. Take a look at web client software factory for an example of how to use object builder to inject your presenter into asp.net views.


You've piqued my curiosity... I thought the WorkItems were meant to manage state, which I always took to mean the set of models being presented by the presenter. In other words, when the presenter needs model, it gets it from the WorkItem. The View then allows the user to update that model, and when the presenter is done with it, the WorkItem manages persisting the changes. Am I misusing WorkItems?

Thanks for your help,
Bryn Rhodes
Aug 14, 2007 at 4:05 PM


You've piqued my curiosity... I thought the WorkItems were meant to manage state, which I always took to mean the set of models being presented by the presenter. In other words, when the presenter needs model, it gets it from the WorkItem. The View then allows the user to update that model, and when the presenter is done with it, the WorkItem manages persisting the changes. Am I misusing WorkItems?

Thanks for your help,
Bryn Rhodes


I think it is a matter of context. WorkItems are first and foremost an IoC container. They are there to help you with dependency injection and the management of your object hierarchies as well as drive use cases.

How you use them really depends on the context of a use case. I'll give you two examples.

Suppose in use case #1 you have a view that has a Search on it which allows you to search for Employees. The results of the search are displayed to a datagrid on the same View. No other views are involved in this "search use case". In this case, it makes sense for the managing WorkItem to manage the instantiation and lifecycle of this view and its presenter, but not necessarily the model (which would be search results of some kind). It would make more sense for the Presenter of that view to ask for the model directly from a Service or other mechanism. The View talks directly to the Presenter and Presenters are also IoC containers that can be injected with dependencies like services. So why go through yet another object to make the request for the search results (in this case the WorkItem) and have it return the results to the presenter, which then has to update the view? Why not let the Presenter interact directly with the source?

A second case would be a Use Case that requires multiple views to allow for the editing of various parts of the same model. Lets assume that after the SearchResults from the previous case are returned to the SearchView, and a user clicks on a button or link in a datagrid that allows a new UseCase to be started: Employee Editing. Editing an Employee might involve several screens worth of data, all interacting with the same model. In this case, it makes sense to have the WorkItem query for the Employee object graph via a service and pass a reference to that object to all of the presenters that need it via a mechanism like EventBroker. Those presenters can then update their views with the properties of the Employee object that are relevant for that view. Views can update the individual properties, and when the process is completed and ready for saving, the WorkItem can listen for a Command or Event and save the entire object graph in one go.

Thus, how you use a WorkItem depends on your Use Case and the number of views involved. I would say the guiding rule is: What is the simplest way to make it work? Usually that will dictate what to do :)
Aug 14, 2007 at 8:03 PM
Yeah I should mention that the way I do things as described above, is not necessarily the best practices as recommended by CAB/SCSF teams or whatever, but as Chris said it boils down to what works best for your situation at hand, there really is no one right way to do things. If you look at any of the patterns sites you will see lots of variations on MVC/MVP mostly varying based on how active or passive the view is.

In my case the views take a more active role to allow presenter to be reused, and much of the state logic that you put in the workItem is in my presenters because it applies to both views. Some people see this as bad because it is difficult to unit test your views and so it decreases your code coverage, in my opinion (for my situation at least) the return on investment is much higher just unit testing the presenters and the lower levels, buisness logic, etc.. and verifying the view behavior manually. But of course there are alot of variables there, if I were working on a bigger team with lots of really complex view logic, then higher code coverage would be a lot more important.
Aug 15, 2007 at 1:03 AM
Thank you both for your input, it is appreciated. What you're saying makes sense, and the way we have used WorkItems and Presenters to this point pretty much follows what you're describing. I'm relatively new to the CABspace, so I constantly have the nagging sensation that I'm doing something wrong, but it sounds like I'm at least on the right track.

Thanks again,
Bryn Rhodes