In this post (of what may become a series of posts if I find some interest from the community) I compare 2 different approaches for separating view code from business logic in order to reduce the untested surface area while doing TDD.

The Passive View pattern

I have been using the Model View Presenter (MVP) pattern (or more specifically the Passive View pattern) for a long time now, both in the Winforms and WebForms worlds.

The main reasons for this? Testability and separation of concerns. As a TDD adopter, I want to be able to unit test as much logic as I can.

Passive View works fairly well, allowing me to keep the view (usually in the form of a user control) somewhat thin in order to satisfy myself without testing it (you know how difficult/impossible it becomes to unit test a UI screen).

In practice, applications written using Passive View end up having lots of boiler plate code for the communication between the view and the presenter. It also makes it very prone to start putting more knowledge on the view than what I’d like, not only for laziness in trying to avoid forwarding messages (that require very simple processing) to the presenter, but also in some transformations needed to keep the presenter agnostic of the specifics of the UI implementation.

WPF templates to the rescue!

In the Prism project we’ve using the Passive View approach also, as a logical step to adopt WPF when you come from winforms / webforms.

In the last time, though, I have been becoming very fond of another approach that is very easy to implement now using the WPF templating and databinding capabilities that weren’t available before: the Presentation Model pattern. This has been also called Model-View-ViewModel by John Gossman / Dan Crevier (if you haven’t read their blog posts on this topic, you MUST read them).

What I would like to add/highlight in this approach is that in WPF you can enforce keeping your view extremely thin by avoiding the use of UserControls or UI-coupled controls. Instead, you can create DataTemplates of your Presentation Model classes, and those model instances are the objects you’ll add to your Window. When your model gets laid out in the visual tree, WPF will automatically pick up the correct template for that model, and render the model appropriately.

This approach relies extremely on data binding, because there is no code behind at all on the views, just XAML markup.

Most of the times I end up deriving my presentation models from DependencyObject to benefit a lot from dependency properties.

In some cases where UI complexity dictates it, the model may derive from Control instead. "What?!? a model deriving from a Control?". That was my first thought when I came to that possibility, but it was highly biased from my Winforms past. Controls (don’t mistake with UserControls) in WPF are totally lookless and do not rely on the UI, so they can be tested in isolation. To render the appropriate view you’ll need to create a default ControlTemplate (compared to a DataTemplate for plain objects or DependencyObjects). One big benefit about using Controls is that you can maintain a WPF logical tree of presentation models (there are some benefits about this which I won’t cover in this post).

I’m planning on providing you with some code samples in the future, but in the meantime guess what: The latest Prism code drop will be including a spike we did using this approach. You should check it out and see how it feels. Notice that this is just a spike and we are only releasing it in order to get feedback from you guys, and see what is the interest on seeing more of it.

When using the Add Smart Web Reference recipe from the Smart Client Software Factory, it generates a proxy that wraps the original VS generated proxy.

Let’s assume we have a web service named MyService. When you add a Smart Web Reference, Visual Studio will automatically add a Web Reference to the service (a class named MyService that inherits from SoapHttpClientProtocol), and a class named MyServiceProxy, which is the class that wraps the previous one. It will also generate a bunch of other classes and interfaces to support the command queue infrastructure.

We, as SCSF users/developers, are used to add the services to WorkItem.Services collection to be consumed later in this or other modules, in the following way:

private void AddServices() {  WorkItem.Services.AddNew<MyServiceProxy, IMyServiceProxy>(); }

 

 

As you already know by now, you could get a reference to IMyServiceProxy, or even MyServiceProxy, but this wrapper does not expose any properties the original proxy had, so you can’t access the credentials for a service that do requiere some, if you don’t have a reference to the original web service proxy instance. MyServiceProxy does not inherit from SoapHttpClientProtocol so you don’t have access to any member of the original Visual Studio generated proxy class for the web service.

What the previous example does is call the default constructor on MyServiceProxy, which creates a new instance of MyService to wrap. Luckily, the wrapper has an overloaded constructor that receives an instance of the service it wraps, but the problem is we cannot specify the ObjectBuilder which instance we want to use with the previous code.

What we should do instead is the following:

private void AddServices() {  MyService myService = new MyService();  //we could store this instance somewhere for later usage if we want  myService.Credentials = new NetworkCredential(username, password);  //Now we’ll create an instance of the wrapper class with this instance of MyService  MyServiceProxy myServiceProxy = new MyServiceProxy(myService);  //Notice the use of the overloaded constructor  WorkItem.Services.Add<IMyServiceProxy>(myServiceProxy); }

Makes perfect sense, right? Sometimes we are so used to add web services to a workitem the other way, that when we add authentication to them we don’t see the solution at first sight.

Side comment: As many of you’d probably know, the p&p team is working on something called Disconnected Service Agent that will replace the Add Smart Web Reference recipe in the next release of SCSF, with lots of added functionality as it also uses the Offline Application Block.