.NET and me Coding dreams since 1998!

25Nov/105

Naked MVVM – simplest way to do WCF code

How to get testable WCF code in simplest way?

What is the problem?

We all know that creating an instance of service proxy inside of the view model makes writing tests for the view model very hard because during the unit test run we don’t have usually the web service on the other side or even if we do it slows down web tests.

You know how they say

“Unit test is the test which runs without any problem with network cable unplugged”

Like the previous post about simplest possible way to do MVVM, the solution for this problem was covered in so many blog posts that even I am personally aware of a couple of cool and ‘frameworkish’ ways to solve it: use WCF behaviors, create your own ChannelFactory<T> with either sync call in separate thread or IAsyncResult based approach and (my personal favorite) hack the Visual Studio proxy generator. I’m sure there are at least 24 more solutions to do this Smeško

Still, there are two main problems with all the approaches I saw which belong to one of the next two groups:

  1. They deal purely with async based scenarios.
    If I have a service with a method GetForecast(DateTime date), I don’t want to maintain another interface just to get a way to make async call.
  2. They are rocket science type of solutions
    We are all geeks and like nice and shiny toys, but what about regular folks like me and a lot of the readers? Is there a really simple way to do this for “us others”?

Luckily, I think I found one which is definitely not the coolest one and 100% can be enhanced etc, but it is the one which proved to me in my day to day WPF/SL coding to be the easiest one “to grok and use”.

Conceptual solution

imageThe solution follows next design goals:

  • doesn’t require any typing
  • it is using Visual Studio proxy generated with “Add service..” menu action
  • it is using the well documented MethodAsync() invoker, MethodCompleted event subscriber pattern
  • it is using T4 to auto generate code which enhances the VS generated service proxy
  • every service proxy file follows naming convention of ending with word “Proxy”

A year ago, I have blogged in great detail about the unfortunate fact of ServiceClient generated in service proxy not implementing an IServiceClient interface. In case you want to understand what my solution do under the hood go read that blog post now and then continue reading this one. In case “you don’t care how it works as long it is working” here’s a very short summary for you:

ServiceClient generated by proxy generator is marked as partial class.That allows me to create another partial class with same name and namespace outside of proxy which only purpose is to hook the IServiceClient interface I generated manually based on the ServiceClient itself.

In the original blog post I do it manually which ended as a PITA due to the fact that every change of service contract one has to keep updated the interface. As a result of noticing that I waste a lot of time on that, I spent 20 minutes and created a simple T4 class which does that automatically for me.

You can download the source code of end solution here.

Before

Project structure is very trivial. It is vanilla Silverlight project which has a TimerService WCF service doing just this

using System;
using System.ServiceModel;
using System.ServiceModel.Activation;

namespace NakedMVVM.Web
{
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class TimerService
    {
        [OperationContract]
        public string GetTime()
        {
            return "Yes it works on " + DateTime.Now;
        }
    }
}

Once we add a service proxy to NMVVM_WCF project (NOTE that proxy name ends with Proxy)

image

We can happily write now our demoware code “…

namespace NMVVM_WCF
{
    using System.ComponentModel;
    using System.Runtime.Serialization;

    using NMVVM_WCF.TimerServiceProxy;

    public class MainPageViewModel : INotifyPropertyChanged
    {
        public MainPageViewModel()
        {

            TimerServiceClient client = new TimerServiceClient();
            client.GetTimeCompleted += OnGetTimeCompleted;
            client.GetTimeAsync();
        }

        private void OnGetTimeCompleted(object sender, GetTimeCompletedEventArgs e)
        {
            Message = e.Result;
        }

        [DataMember]
        private string message;

        public string Message
        {
            get
            {
                return this.message;
            }
            set
            {
                if (this.message == value)
                {
                    return;
                }
                this.message = value;
                this.OnPropertyChanged("Message");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

Nothing wrong with this code per se, just it makes unit testing of the view model much harder task then it should be…

After

To fix this problem, let’s do next 2 steps:

  • download the T4 template file (no need to look in what it contains at all) from here .
  • add the file to the root folder of NMVVM_WCF project using VS IDE “Add existing item”

As a result of this activities t4 template was executed and a file with ClientEnhancer was auto-generated with next content

	namespace NMVVM_WCF.TimerServiceProxy
	{
		public partial interface ITimerServiceClient
		{
			#region Events
			event System.EventHandler GetTimeCompleted;
			event System.EventHandler OpenCompleted;
			event System.EventHandler CloseCompleted;
			#endregion Events

			#region Methods
			 void GetTimeAsync();
			 void GetTimeAsync(object userState);
			 void OpenAsync();
			 void OpenAsync(object userState);
			 void CloseAsync();
			 void CloseAsync(object userState);
			#endregion Methods
		}

		public partial class TimerServiceClient  : ITimerServiceClient
		{
		}
	}

As you can guess, that's complete code I was coding by hand and keep it updated manually with service contract changes. Having this in place it is quite easy to change ViewModel to accept the IServiceClient as a constructor parameter

        public MainPageViewModel(ITimerServiceClient client)
        {
            client.GetTimeCompleted += OnGetTimeCompleted;
            client.GetTimeAsync();
        }

        private void OnGetTimeCompleted(object sender, GetTimeCompletedEventArgs e)
        {
            Message = e.Result;
        }

The only thing left is to update the MainPage.xaml.cs file

namespace NMVVM_WCF
{
    using NMVVM_WCF.TimerServiceProxy;

    public partial class MainPage
    {
        public MainPage()
        {
            InitializeComponent();
            DataContext = new MainPageViewModel(new TimerServiceClient());
        }
    }
}

And that’s it – application works like it was and we have a highly testable view model using only service client interface which is easy to stub/mock.

Having a hard time figuring out path from “before” to “after”? Here’s a short video showing step by step things just described

You can download the source code of end solution here.

Aftermath

My own version of this T4 template, beside the T4 template code used in this blog post is also auto filling IoC container with mappings to all of service clients and its interfaces generated by template. That auto generation combined with auto MVVM wire up I described in first post allow me to have this “TDD enabling of WCF service proxies” fully automated.

I decided not to put that additional template code so it won’t bloat the post with IoC containers etc, but it is VERY easy to modify and customize the T4 template – even if you never did it spend 20 minutes looking at .tt file I shared for this post and I guarantee you – you’ll get it.

The only downside of this approach is that you have to manually drop the T4 template file to every project with service proxies which in my case is not the problem at all – I add it once and after that it keeps things in sync on its own.

I am really not sure why Microsoft is not doing this in the default proxy generation process – it is not breaking anything or damaging backward compatibility and it enables easy testing. I was experimenting modifying the Visual Studio proxy generator myself, but I decided to abandon it (even it was working at the end) due to required registry modifications etc. In my opinion, dropping one file in project without any other requirements to make it testable is more transparent then other approaches and everyone could do this.

What do you think about it? Is it simple enough?

Filed under: Uncategorized 5 Comments
7Nov/1023

Naked MVVM–simplest possible MVVM approach

How to do MVVM in simplest possible way?

Yes, I am aware that there are at least 50 “How to do MVVM” blog posts and well known frameworks: prism, MVVM Light, Caliburn etc. Still, my friend Slobodan Pavkov convinced me to write a post and explain the approach I am personally using in my code, because (as he believes) it is so simple that it can be useful to someone -  so here I am - writing it down.
Idea is so simple that I guess it is very possible someone already blogged about it and if so please let me know so I could link that blog post here. I presume you know what MVVM already is – if not go read some of the hundreds blog posts about that and once you get it come back. My sample is done in WPF (as that is my LOB platform of choice) but it works without any changes in Silverlight too.
As all MVVM framework I had to pick a name reflecting the spirit of my “framework” and I ended with “Naked MVVM” because it reflects design principles I respect:
  1. No base classes of any kind required for framework
  2. No interfaces of any kind required for framework
  3. No attributes of any kind required for framework
  4. View first – Blend friendly & simple composition
  5. IoC enabled
  6. Works out of box as much as possible

Basic ideas behind “Naked MVVM”

Scenario

Simple MVVM framework requires simple possible problem: show in MVVM way a text box showing current date. That’s it – let’s roll.

You can download the source code of end solution here.

No base classes, interfaces and attribute

Usual implementations of MMVM I’ve seen usually have ViewModel<TView> base class and/or some form of IView view abstraction etc.
Here’s how View looks like in my approach
namespace NakedMVVM
{
    public partial class MainWindowView
    {
        public MainWindowView()
        {
            InitializeComponent();
        }
    }
}
And here is the view model containing all of the necessary requirements from my Naked MVVM framework
namespace NakedMVVM
{
    public class MainWindowViewModel
    {
    }
}
As you can tell from the code above, there are ZERO requirements from view and view model.

Wiring up the view and the view model

s you already know, the whole MVVM pattern is based on the idea that view data binds to a view model which then talks to a model.
image
A lot of samples I’ve seen, define some form of view abstraction which should enable view model to communicate with view on framework level.
All of those samples ignore one simple but VERY IMPORTANT fact – there is such abstraction already baked in .NET – FrameworkElement. Every view (user control, window etc.) inherits from the FrameworkElement and can be casted to it. The reason why I picked it up is that the framework element has a DataContext member (to bad it is not defined in some interface so I could replace FrameworkElement with it). Setting a user control data context to some value results with all of the controls in that window/user control being bounded to the same value.
To codify that thought...
namespace NakedMVVM
{
    using System.Windows;

    public class MainWindowViewModel
    {
        public MainWindowViewModel(FrameworkElement frameworkElement)
        {
            frameworkElement.DataContext = this;
        }
    }
}
The problem here is how an IoC container (one of the requirements above is to use IoC) can resolve this generic FrameworkElement constructor parameter? That question is exactly the reason why we have all of the IView and IView<T> in the MVVM blog posts. To me that well documented approach is an overkill because we create entities just to hold our infrastructure. Much better approach could be to resolve a framework element from a IoC container using a well known key. There are many way how to do that but let here illustrate it in the simplest to digest form using the ServiceLocator.
namespace NakedMVVM
{
    using System.Windows;

    using Framework;

    public class MainWindowViewModel
    {
        public MainWindowViewModel()
        {
            var frameworkElement = ServiceLocator.IoC.Resolve("MainView");
            frameworkElement.DataContext = this;
        }
    }
}
As you can see here, view model becomes a data context of a view without any artificial code artifacts created to enable that. If I wouldn’t have to respect my design principle #1 “No base classes of any kind required” I could extract this class to base view model class and have it applicable on all view models.
namespace NakedMVVM
{
    using System.Windows;
    using Framework;

    public class MainWindowViewModel : ViewModel
    {
    }

    public abstract class ViewModel
    {
        public ViewModel()
        {
            var frameworkElement = ServiceLocator.IoC.Resolve(this.GetType().Name.Replace("Model",""));
            frameworkElement.DataContext = this;
        }
    }
}
Too bad I am not allowed to do that so I am again deleting all of the changes in this ViewModel and restore it back to be an empty class with no base class and no wire-up code in it. To see what I do in my code you would have to be patient for a little bit more because I need to explain first may way of …

Filling the IoC container

In most MVVM samples, there is a bootstrapper class where developer enlist all of the IoC mappings. In this example it could be something like this
using System.Windows;

namespace NakedMVVM
{
    using Framework;

    public partial class App : Application
    {

        public App()
        {
            ServiceLocator.IoC.RegisterType<FrameworkElement,MainWindowView>("MainWindowView");
        }
    }
}
imageJust by looking at this single line of code, it becomes obvious that:
  • I have to do the same thing for every user control/window I have
  • I map always framework element to a user control/windows
  • The key I use to store it in IoC is the same as the name of user control/window
Every WPF/SL developer I know (including me) when doing MVVM follows the next naming convention:
  • every user control is suffixed with “View” and
  • every view model of a control is suffixed with “ViewModel”
In concrete case of the sample used in this blog post, user control is named MainWindowView and her view model class MainWindowViewModel
If we combine the 3 obvious facts given above with the naming convention we could easily come to the same idea as I did:
“Iterate all of the types in current assembly. Each one of them which name ends with “View” map as framework element using the full type name as a key. Each one of them which name ends with a “ViewModel” map as object with a full type name as a key.”
Translating that thought into a C# code class IoCBuilder in this sample was created containing this
namespace Framework
{
    using System;
    using System.Reflection;
    using System.Windows;
    using System.Windows.Controls;

    public static class IoCBuilder
    {
        public static void CollectViewAndViewModelMappings()
        {
            foreach (var type in Assembly.GetCallingAssembly().GetTypes())
            {
                var typeIsUserControl = type.BaseType == typeof(UserControl);
                if (typeIsUserControl)
                {
                    var typeIsView = type.Name.EndsWith("View", StringComparison.InvariantCultureIgnoreCase);
                    if (typeIsView)
                    {
                        ServiceLocator.IoC.RegisterType(typeof(FrameworkElement), type, type.FullName);
                    }
                }
                else
                {
                    var typeIsViewModel = type.Name.EndsWith("ViewModel", StringComparison.InvariantCultureIgnoreCase);
                    if (typeIsViewModel)
                    {
                        ServiceLocator.IoC.RegisterType(typeof(object), type, type.FullName);
                    }
                }
            }
        }
    }
}
Now when we have this code in place, we can replace the explicit mappings from our bootstrapper class to a framework call
namespace YAMVVM
{
    using System.Windows;
    using Framework;

    public partial class App : Application
    {
        public App()
        {
            IoCBuilder.CollectViewAndViewModelMappings();
        }
    }
}
Major upside of this approach (at least for me) is that respects design principle #6 and allows me to just add a view and a view model without thinking about IoC mappings etc.

My way of wiring up view and view model

Having in mind the content of IoC container and design principle #4 (Blendable framework) after a lot of experimenting I’ve realized that the behavior is the most suitable way of doing the wire up.
The behavior itself is quite trivial and it it reflecting the same approach as shown above in explicit wire up sample code.
namespace Framework.Behaviors
{
    using System.Windows;
    using System.Windows.Interactivity;
    using Framework;

    public class AutoWireUpViewModelBehavior : Behavior<UIElement>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            var view = (FrameworkElement)this.AssociatedObject;
            var viewModelName = string.Format("{0}Model", view.GetType().FullName);
            var viewModel = ServiceLocator.IoC.Resolve<object>(viewModelName);
            view.DataContext = viewModel;
        }
    }
}
Code is quite simple: pointer to a user control is being passed to a behavior. Following the naming convention explained above, I add the “Model”to the name of the view so I would get the specific view model key which I use to resolve view model from a container. Once resolved view model, I set to a DataContext of a user control being passed to a behavior. Same approach as the one in explicit sample, just encapsulated in the behavior.
Now when there is a framework level behavior, only thing a designer has to do to wire up a view and view model (I emphasize here again that both of them are following the #1-#3 principles and not having any base class, interface etc) is to fire up a blend and just drag&drop the AutoWireUp behavior to a control.
imageimage
Off course, for us developers executing next R# snippet and resolving namespaces is maybe more suitable solution
    <i:Interaction.Behaviors>
        <Framework:AutoWireUpViewModelBehavior />
    </i:Interaction.Behaviors>
Regardless of which way you would prefer, the end goal is achieved: view and view model are wired up on a unobtrusive way removing the need for infrastructure bloat used usually to enable that.

Putting it to work

If we run our sample, everything will work just fine (even with view and view model being completely empty) except we won’t see the current date on the screen so we can’t know for sure if it work or not, aren’t we?
Let modify the view to its final state
<Window x:Class="NakedMVVM.MainWindowView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Framework="clr-namespace:Framework.Behaviors;assembly=Framework"
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
    <i:Interaction.Behaviors>
        <Framework:AutoWireUpViewModelBehavior />
    </i:Interaction.Behaviors>
    <Grid>
        <TextBlock Text="{Binding HeadingCaption}" />
    </Grid>
</Window>
and the view model
namespace NakedMVVM
{
    using System;
    using System.ComponentModel;

    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public MainWindowViewModel()
        {
            HeadingCaption = "Yes it works on " + DateTime.UtcNow;
        }

        private string headingCaption;

        public string HeadingCaption
        {
            get { return this.headingCaption; }
            set
            {
                this.headingCaption = value;
                this.OnPropertyChanged("HeadingCaption");
            }
        }

        #region The usual INPC implementation
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion    }
    }
}
Run the app
image
See, it works Smeško
You can download the source code of end solution here.
What do you think? Have you seen this approach in whole somewhere? Does it makes sense to you or it look to you just-another-fluffy-pattern-thing?
Looking forward to hear your thoughts on my approach!
Filed under: Uncategorized 23 Comments