Posted Monday, October 26, 2009 by Nigel Sampson
In the previous posts we've been retrieving our data from a synchronous data source, for the most part in Silverlight we'll be retrieving data sources from aseparate server, in this case through a WCF Service. Silverlight has a restriction that all network calls must be asynchronous in order to avoid locking up the browser UI (a good thing). It does however make the code a little more complicated.
The functionality of the CocktailsService will stay the same, we're just going to migrate it over to the server and host it as a WCF service. The code for the service is remains exactly the same, just shifted now to the server and hosted as a WCF service. If you'd like to learn more about setting up a WCF service you can read more on MSDN.
[ServiceContract]
public interface ICocktailService
{
[OperationContract]
IEnumerable<Cocktail> GetCocktails();
[OperationContract]
IEnumerable<Cocktail> GetCocktailsSimilarTo(Cocktail cocktail);
}
Then we generate a client proxy using Visual Studios "Add Service Reference". The proxy generated includes any types from the data contracts (the Cocktail class), the proxy client (CocktailsServiceClient) and a service interface (ICocktailsService). One thing to notice if you've done any WCF work before is that the interface doesn't contain the events exposed by the actual client class.
We'll now need to alter our Cocktails view model to deal with the new interface. Basically it's a relatively simple change from synchronous methods to using async ones. It should look like this...
public class CocktailsViewModel : ViewModelBase<CocktailsViewModel>
{
private readonly ICocktailService cocktailService;
public CocktailsViewModel(ICocktailService cocktailService)
{
this.cocktailService = cocktailService;
AvailableCocktails = new ObservableCollection<Cocktail>();
SimilarCocktails = new ObservableCollection<Cocktail>();
GetSimilarCocktailsCommand = new DelegateCommand<Cocktail>(GetSimilarCocktails);
cocktailService.BeginGetCocktails(OnGetCocktails, null);
}
private void OnGetCocktails(IAsyncResult ar)
{
var cocktails = cocktailService.EndGetCocktails(ar);
AvailableCocktails.AddRange(cocktails);
}
public ObservableCollection<Cocktail> AvailableCocktails
{
get;
set;
}
public ObservableCollection<Cocktail> SimilarCocktails
{
get;
set;
}
public ICommand GetSimilarCocktailsCommand
{
get;
private set;
}
protected void GetSimilarCocktails(Cocktail cocktail)
{
cocktailService.BeginGetCocktailsSimilarTo(cocktail, OnGetCocktailsSimilarTo, null);
}
private void OnGetCocktailsSimilarTo(IAsyncResult ar)
{
var cocktails = cocktailService.EndGetCocktailsSimilarTo(ar);
SimilarCocktails.Replace(cocktails);
}
}
There is a slight problem with the code above. Silverlight expects property changed notifications (including collection changed from ObservableCollection) to be on the UI thread. The async result methods will be on a separate thread (The generated service client will dispatch the OnXCompleted events back to the UI thread but not the asynch methods). There a couple of ways we can solve this.
- Manually dispatch any updates to properties back to the UI thread.
- Create our own ObservableCollection that ensures all notifications are on the correct thread. An example of this can be found at "Adding to an ObservableCollection from a background thread"
For this example we'll just be going with the first. We'll update our ViewModelBase to take a reference to the Application dispatcher and have a simple helper method.
protected ViewModelBase()
{
Dispatcher = Deployment.Current.Dispatcher;
}
protected Dispatcher Dispatcher
{
get; private set;
}
protected void InvokeOnUIThread(Action action)
{
Dispatcher.BeginInvoke(action);
}
We then alter the offending methods to use the helper.
private void OnGetCocktails(IAsyncResult ar)
{
var cocktails = cocktailService.EndGetCocktails(ar);
InvokeOnUIThread(() => AvailableCocktails.AddRange(cocktails));
}
private void OnGetCocktailsSimilarTo(IAsyncResult ar)
{
var cocktails = cocktailService.EndGetCocktailsSimilarTo(ar);
InvokeOnUIThread(() => SimilarCocktails.Replace(cocktails));
}
Our updates to the collections will be dispatched off to the UI thread and the exception will be avoided.

Posted Sunday, October 11, 2009 by Nigel Sampson
There are a couple of great reasons for using a UI separation pattern such as Model, View, ViewModel (or the more common MVP and MVC), the first being that with the application logic separated from the view logic the application becomes easier to maintain. Secondly it's usually easier for a designer and developer to work on the separate areas and integrate them at a later date (this actually helps enforce the separation). And thirdly by having the application logic away from the UI it becomes much easier to test.
While you can do UI testing with the Silverlight testing framework it becomes a hell of a lot easier when you have a nice separation. We're doing to be using a dependency injection framework (in this caseNinject) to build the view models and inject the services. This'll allow us to do interaction based unit testing on the view model using Rhino Mocks.
Overall our goal will be to refactor the existing ViewModel to break it's dependency on CocktailsService and increase it's testability. We'll create a Service Locator that will be an Application resource and serve as almost a "ViewModel factory" and then instead of directly creating our ViewModel in xaml we'll bind our Data Context to the Service Locator.
Our first step will be inverting the dependency the ViewModel has on the Cocktails Service, we'll extract an interface for the service and use constructor injection to pass the service to the ViewModel where it'll be stored, otherwise the view model remains the same.
public interface ICocktailService
{
IEnumerable<Cocktail> GetCocktails();
IEnumerable<Cocktail> GetCocktailsSimilarTo(Cocktail cocktail);
}
public CocktailsViewModel(ICocktailService cocktailService)
{
this.cocktailService = cocktailService;
AvailableCocktails = new ObservableCollection<Cocktail>();
SimilarCocktails = new ObservableCollection<Cocktail>();
GetSimilarCocktailsCommand = new DelegateCommand<Cocktail>(GetSimilarCocktails);
AvailableCocktails.AddRange(cocktailService.GetCocktails());
}
We can now test that the ViewModel exposes the available Cocktails, passes the command parameter to the service and exposes the similar cocktails.
[TestClass]
public class CocktailsViewModelFixture
{
private readonly List<Cocktail> sampleCocktails = new List<Cocktail>
{
new Cocktail
{
Id = 1,
Ingredients = new string[] {},
Name = "Test"
}
};
[TestMethod]
public void ConstuctionRetrievesAvailableCockstails()
{
var cocktailService = MockRepository.GenerateMock<ICocktailService>();
cocktailService.Expect(c => c.GetCocktails()).Return(Enumerable.Empty<Cocktail>());
new CocktailsViewModel(cocktailService);
cocktailService.VerifyAllExpectations();
}
[TestMethod]
public void ConstuctionExposesAvailableCockstails()
{
var cocktailService = MockRepository.GenerateStub<ICocktailService>();
cocktailService.Stub(c => c.GetCocktails()).Return(sampleCocktails);
var viewModel = new CocktailsViewModel(cocktailService);
Assert.AreEqual(sampleCocktails.Count, viewModel.AvailableCocktails.Count);
}
[TestMethod]
public void GetSimilarCocktailsForwardsCommandParameter()
{
var selectedCocktail = new Cocktail();
var cocktailService = MockRepository.GenerateMock<ICocktailService>();
cocktailService.Stub(c => c.GetCocktails()).Return(Enumerable.Empty<Cocktail>());
cocktailService.Expect(c => c.GetCocktailsSimilarTo(selectedCocktail)).Return(Enumerable.Empty<Cocktail>());
var viewModel = new CocktailsViewModel(cocktailService);
viewModel.GetSimilarCocktailsCommand.Execute(selectedCocktail);
cocktailService.VerifyAllExpectations();
}
[TestMethod]
public void GetSimilarCocktailsExposesSimilarCocktails()
{
var selectedCocktail = new Cocktail();
var cocktailService = MockRepository.GenerateMock<ICocktailService>();
cocktailService.Stub(c => c.GetCocktails()).Return(Enumerable.Empty<Cocktail>());
cocktailService.Stub(c => c.GetCocktailsSimilarTo(selectedCocktail)).Return(sampleCocktails);
var viewModel = new CocktailsViewModel(cocktailService);
viewModel.GetSimilarCocktailsCommand.Execute(selectedCocktail);
Assert.AreEqual(sampleCocktails.Count, viewModel.SimilarCocktails.Count);
}
}
Astute readers will notice that because our ViewModel doesn't have a parameterless constructor we can't create it directly in xaml. This is correct, instead we'll be delegating the construction of the ViewModel to a Ninject kernel. We'll create a ServiceLocator that will be an Application Resource (in App.xaml), it will create the Ninject kernel and register the appropriate dependencies.
public class ServiceLocator
{
private readonly IKernel kernal;
public ServiceLocator()
{
kernal = new StandardKernel(new CocktailModule());
}
public CocktailsViewModel CocktailsViewModel
{
get
{
return kernal.Get<CocktailsViewModel>();
}
}
}
public class CocktailModule : StandardModule
{
public override void Load()
{
Bind<CocktailsViewModel>().ToSelf();
Bind<ICocktailService>().To<CocktailService>();
}
}
<Application.Resources>
<cx:ServiceLocator x:Key="ServiceLocator"/>
</Application.Resources>
For simplicities sake I have a simple module that will register the dependencies we need.
Unfortunately there's no nice GUI to hook the ViewModel up anymore we have to write our own Binding expression, but it's not too bad. This binds the DataContext of the UserControl to the property "CocktailsViewModel" which is in turn created by the Ninject kernal, injecting the appropriate dependencies.
DataContext="{Binding Path=CocktailsViewModel,Source={StaticResource ServiceLocator}}"
We're now back to where we were before but now with a unit tested view model. Later on I'll do a post on integration testing the entire stack.

Posted Thursday, September 24, 2009 by Nigel Sampson
In the first post of the series we looked at using Binding expressions to display data from the ViewModel on our screen. The other major part of our interaction is having the view invoke functionality in the ViewModel. In the MVVM pattern this is done using the Command pattern, specifically the ICommand interface.

A Command object encapsulates an action the user can take and is exposed by the ViewModel. Unfortunately Silverlight unlike WPF doesn't have any built in support for Commands beyond the actual interface itself. All the major Silverlight frameworks such as Prism,Caliburn etc has their own variation on how they should be implemented (usually through Attached Behaviors).
Given that we want to keep our MVVM structure "Blendable" we'll be using the Behaviors that come with Blend. What'll we be doing is creating an ExecuteCommandAction that we can trigger using any Blend trigger, this action will be bound to a ICommand exposed by the ViewModel.
In the current version of Silverlight standard behaviors don't support Binding, there is a work around I discussed earlier on this blog by PeteBlois using BindingListeners and exposing Bindings rather than ICommand. You can view more on this at his blog. The code for our new action looks like this, it shouldn't have to be this complicated but thats another rant.
public class ExecuteCommandAction : TriggerAction<FrameworkElement>
{
private readonly BindingListener commandListener;
private readonly BindingListener commandParameterListener;
public ExecuteCommandAction()
{
commandListener = new BindingListener();
commandParameterListener = new BindingListener();
}
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(Binding), typeof(ExecuteCommandAction), new PropertyMetadata(null, OnCommandChanged));
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register("CommandParameter", typeof(Binding), typeof(ExecuteCommandAction), new PropertyMetadata(null, OnCommandParameterChanged));
public Binding Command
{
get
{
return (Binding)GetValue(CommandProperty);
}
set
{
SetValue(CommandProperty, value);
}
}
public Binding CommandParameter
{
get
{
return (Binding)GetValue(CommandParameterProperty);
}
set
{
SetValue(CommandParameterProperty, value);
}
}
private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((ExecuteCommandAction)d).OnCommandBindingChanged(e);
}
private static void OnCommandParameterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((ExecuteCommandAction)d).OnCommandParameterBindingChanged(e);
}
private void OnCommandBindingChanged(DependencyPropertyChangedEventArgs e)
{
commandListener.Binding = (Binding)e.NewValue;
}
private void OnCommandParameterBindingChanged(DependencyPropertyChangedEventArgs e)
{
commandParameterListener.Binding = (Binding)e.NewValue;
}
protected override void OnAttached()
{
base.OnAttached();
commandListener.Element = AssociatedObject;
commandParameterListener.Element = AssociatedObject;
}
protected override void OnDetaching()
{
base.OnDetaching();
commandListener.Element = null;
commandParameterListener.Element = null;
}
protected override void Invoke(object parameter)
{
var command = commandListener.Value as ICommand;
if(command == null)
return;
var commandParameter = commandParameterListener.Value;
if(command.CanExecute(commandParameter))
command.Execute(commandParameter);
}
}
The functionality we're going to provide is to list the available cocktails, then once a user selects one we show similar cocktails (similar being defined as sharing two or more ingredients). We've modified the Cocktails service to look like this.
public class CocktailService
{
private readonly List<Cocktail> cocktails = new List<Cocktail>
{
new Cocktail
{
Id = 1,
Name = "Black Russian",
Ingredients = new [] { "Vodka", "Kahlua" }
},
new Cocktail
{
Id = 2,
Name = "White Russian",
Ingredients = new[] { "Vodka", "Cream", "Kahlua" }
},
new Cocktail
{
Id = 3,
Name = "Gin and Tonic",
Ingredients = new[] { "Gin", "Tonic" }
}
};
public IEnumerable<Cocktail> GetCocktails()
{
return cocktails;
}
public IEnumerable<Cocktail> GetCocktailsSimilarTo(Cocktail cocktail)
{
return from c in cocktails
where c.Ingredients.Intersect(cocktail.Ingredients).Count() >= 2 && c.Id != cocktail.Id
select c;
}
}
We also need an implementation of ICommand, I've gone with a very simple DelegateCommand which simply has an executed command invoke a method on the ViewModel.
public class DelegateCommand<T> : ICommand
{
public event EventHandler CanExecuteChanged;
private readonly Action<T> action;
private readonly Func<T, bool> predicate;
public DelegateCommand(Action<T> action)
{
if(action == null)
throw new ArgumentNullException("action");
this.action = action;
predicate = t => true;
}
public DelegateCommand(Action<T> action, Func<T, bool> predicate)
{
if(action == null)
throw new ArgumentNullException("action");
if(predicate == null)
throw new ArgumentNullException("predicate");
this.action = action;
this.predicate = predicate;
}
protected virtual void OnCanExecuteChanged(EventArgs e)
{
var canExecuteChanged = CanExecuteChanged;
if(canExecuteChanged != null)
canExecuteChanged(this, e);
}
public void RaiseCanExecuteChanged()
{
OnCanExecuteChanged(EventArgs.Empty);
}
public bool CanExecute(object parameter)
{
return predicate((T)parameter);
}
public void Execute(object parameter)
{
action((T)parameter);
}
}
Now we have all the pieces to build our new ViewModel. As before we expose our ObservableCollection of AvailableCocktails which is populated on construction, we'll now elso expose a similar collection of SimilarCocktails. Now the new stuff, we'll create a private method that takes a cocktail and fills the SimilarCocktails with ones similar to the parameter. We then wrap this method with a DelegateCommand and expose it via an ICommand property.
public class CocktailsViewModel : ViewModelBase<CocktailsViewModel>
{
private readonly CocktailService cocktailService = new CocktailService();
public CocktailsViewModel()
{
AvailableCocktails = new ObservableCollection<Cocktail>();
SimilarCocktails = new ObservableCollection<Cocktail>();
GetSimilarCocktailsCommand = new DelegateCommand<Cocktail>(GetSimilarCocktails);
AvailableCocktails.AddRange(cocktailService.GetCocktails());
}
public ObservableCollection<Cocktail> AvailableCocktails
{
get;
set;
}
public ObservableCollection<Cocktail> SimilarCocktails
{
get; set;
}
public ICommand GetSimilarCocktailsCommand
{
get; private set;
}
protected void GetSimilarCocktails(Cocktail cocktail)
{
SimilarCocktails.Replace(cocktailService.GetCocktailsSimilarTo(cocktail));
}
}
Excellent, our ViewModel is complete, notice we've done all the functionality of the page without worrying about how the UI will look or feel. I'm going to assume that while I'm building this our designer is building a lovely interface for our application (hopefully using some of theSketchFlow and SampleData functionality in Blend). The screencast shows how to hook up the View to the ViewModel using Blend.
If you want to download the source of the project you can find it here, (it does contain some of the code for the next post).
