Screencast: Real-World MVVM with WCF RIA Services

Great news! I have just published an online tutorial and screencast for using the Simple MVVM Toolkit to build Real-World MVVM Apps with WCF RIA Services.

Screencast Part 1 Streaming (watch now) or Download (offline for pc or mobile device)
Screencast Part 2 Streaming (watch now) or Download (offline for pc or mobile device)

mvvmria-screencast

You can also download the code for the tutorial and read the tutorial.

This tutorial and screencast will help you quickly get up to speed on using the Simple MVVM Toolkit together with WCF RIA Services to build a real-world MVVM Silverlight application.  Entities are persisted to the Northwind sample database (using SQL Server 2008 Express) through an ADO.NET Entity Data Model.  WCF RIA Services projects entity classes to a Silverlight client app, where they are change-tracked so inserts, updates and deletes can be sent to the service where they are persisted in a single transaction.  Service agents are injected by a ViewModel locator with MEF (Managed Extensibility Framework) using declarative attributes. The tutorial also demonstrates how to build unit tests against a ViewModel and run them asynchronously.  Here are the main steps you perform:

  1. Create a new project in Visual Studio 2010 using the SimpleMvvmRiaServices project template installed by the Simple MVVM Toolkit.
    • The template creates a solution with three projects: a Silverlight project, a Unit Testing project, and a Web Host project.
    • The Silverlight and Test projects reference the Simple MVVM Toolkit and contain all the required classes.  Just press F5 to see a fully functional MVVM application.
    • The Silverlight and Web projects have a WCF RIA Services link.
  2. Add an ADO.NET Entity Data Model to the Web project.
    • The tutorial uses Entity Framework as the Object-Relational Mapper, but you can use any ORM you wish, for example, NHibernate.
  3. Add a Domain Service class to the Web project.
    • When you build the project a Domain Context class is generated on the Silverlight client, which includes entities from your data model that are automatically change-tracked
    • RIA Services also provides end-to-end validation out of the box
  4. Add a service agent interface that is implemented by both mock and real service agents.
    • The real service agent loads a query from the domain context
  5. Using the SimpleMvvmViewModel Visual Studio item template, add a ViewModel to the Silverlight project.
    • Use the mvvmprop code snippet to add properties to the ViewModel
    • Add methods that call service agent methods for retrieving and saving entities
  6. Expose the ViewModel as a property on the ViewModelLocator class (which is already present in the Silverlight project)
    • Use the mvvminjectedlocator code snippet to add the ViewModel property, which injects the service agent (real or mock) into the ViewModel using MEF
  7. Use the SimpleMvvmViewModelTests item template to add a unit test for the ViewModel to the Test project
  8. Add a View to the project using the Silverlight Page item template
    • Using the mvvmcontext XML snippet, set the DataContext of the View to the ViewModel property of the locator
    • Use the mvvmevent XML snippet to add event triggers that call ViewModel methods
    • Bind controls to ViewModel properties
    • Wire up event handlers in the View code-behind to handle notifications from the ViewModel
  9. Use the SimpleMvvmViewModelDetail Visual Studio item template to add a ViewModel for adding or editing individual entities.
  10. Add a View using the Silverlight Child Window item template and bind controls to properties of the Model property on the ViewModel.

When you run the completed project, you will be able both to retrieve and update entities from a database using WCF RIA Services.

If you are unfamiliar with WCF RIA Services you can watch a recording of a webinar I gave on the topic for DevelopMentor. Enjoy!

Posted in Technical | 23 Comments

Simple MVVM Toolkit versus MVVM Light Toolkit

Now that I’ve released Simple MVVM Toolkit version 2, people are starting to ask how it stacks up against some of the other MVVM Toolkits out there. (MVVM, which stands for Model-View-ViewModel, is a UI design pattern that provides better maintainability, testability and designability.)  When it comes to deciding which toolkit best suites your needs, there is a spectrum of choices.  On one end are very powerful frameworks, such as Prism or Caliburn (Micro), which offer a plethora of features but have a rather steep learning curve. At the other end there are toolkits that are very lightweight, with the basic features you need to build apps using the MVVM design pattern.

Simple MVVM Toolkit would fall into the latter category.  It is designed with the idea that a design based on simplicity reduces the time spent learning a framework and makes your apps easier to develop and maintain.  But just because a framework is simple does not make it trivial.  In fact, Simple MVVM Toolkit includes just about every feature you need to build real-world line of business apps based on the MVVM design pattern.  However, instead of trying to accommodate every possible use case, my toolkit focuses on the most common scenarios to provide the best possible value with a minimum amount of friction.

So if you need an MVVM toolkit that’s offers basic features and is relatively easy to use, the range of choices narrows to a few options.  Due to time restrictions, I will have to save an exhaustive survey of toolkits for a future post.  But here I will compare Simple MVVM Toolkit to the most popular “basic” toolkit out there: MVVM Light Toolkit by Laurent Bugnion.  Disclaimer: Choice of toolkits depends greatly on your requirements and is a matter of personal preference. This comparison is meant to highlight features and benefits of the Simple MVVM Toolkit and should not be construed as a criticism of any other toolkit.

compare

Platforms

Both Simple MVVM and MVVM Light toolkits support WPF, Silverlight and Windows Phone clients. Both toolkits come with three assemblies offering basically the same functionality, each targeted to a different platform.

Support

The area where Simple MVVM Toolkit really shines in the ease with which you can quickly get up and running.  Presently MVVM Light requires a manual installation, but the download for Simple MVVM is an installer which gives you the assembly binaries, external libraries, samples and source code.  It also registers the toolkit assemblies so that they appear in the Visual Studio Add References dialog, and it installs Visual Studio project and item templates, code and xml snippets.  Everything is there and it just works.  And if you download the Simple MVVM Toolkit from the Visual Studio Extensions Gallery, you’ll also be notified when a new version of the toolkit is released on the gallery.

MVVM Light does not seem to offer much in the way of documentation.  All that’s listed on the Documentation tab of the project are links to a couple blog posts and a few screen shots.  Simple MVVM Toolkit, on the other hand, has Documentation that includes the following topics: Introduction, Features, Prerequisites, Download Contents, Installation, Samples, and a Programming Reference.  In addition there is a Getting Started topic which correlates to a screencast and provides step-by-step instructions for creating a Silverlight app using the toolkit.  I also explore various features of the toolkit on my blog, with a listing posted on the Discussions page of the toolkit project, and I support a Facebook group for the toolkit.

While Laurent lists a number of articles and tutorials that have been written about MVVM Light, I was unable to locate very many samples available for download which demonstrate how to use his toolkit and its various features.  He has presented some workshops for which you can download the code, and there are some tutorials by Jesse Liberty and Chris Koenig.  That’s not too bad, but, perhaps because I prefer to learn by example, I would like to have something more like a reference application.

That is why I have focused a great deal of my energy on building two categories of sample applications that are installed with the Simple MVVM Toolkit.  One is an assortment of small samples, each illustrating a particular feature or aspect of the toolkit: Property Association, Enums, Async, Dependency Injection, Messaging, Navigation, and RIA Services, as well as Getting Started samples for Silverlight, WPF and Windows Phone.  The other category of samples consists of a three-part series showing the development of an end-to-end MVVM Silverlight app that invokes operations on a WCF service and interacts with a SQL Server database.  Part 1 has basic functions and shows how to use events for dialogs and two-way communication between Views and ViewModels.  Part 2 demonstrates navigation, messaging, dependency injection, unit testing and async operations.  Part 3 ports the app to WCF RIA Services and shows how to leverage it for entity persistence and batch updates.

Usability

Both Simple MVVM and MVVM Light toolkits ship with Visual Studio project and item templates, as well as some code snippets.  I would say that the project templates for MVVM Light are rather basic.  There is a ViewModeLocator, which exposes a static MainPageViewModel with a single property and no methods or commands. The MainPage view has a TextBlock that is bound to the property on the MainPageViewModel. That’s it.  Simple MVVM Toolkit also has ViewModelLocator, ViewModel and View classes, but the locator supplies a service agent (represented by an interface), which the ViewModel uses to create a new Model.  In addition Simple MVVM includes a multi-project Visual Studio template that supplies a Silverlight client, a WCF RIA Services web host, and a Unit Testing project.  This is designed to be a real-world example with navigation, modal dialogs, messaging and saving changes. Each project template includes a ReadMe file with step-by-step instructions.

While both toolkits include a number of code snippets, Simple MVVM also sports XML snippets that can be used to add bindings and event triggers to XAML files.

Features

Both toolkits provide a ViewModel base class that implements INotifyPropertyChanged with lambda expressions to support type-safe two-way data binding.  Both toolkits supply a DelegateCommand class for wiring up ViewModel commands.  Commands play a more central role in MVVM Light, which has an EventToCommand behavior, but I favor Blend-style event triggers so that you can call any ViewModel method from any event in the view without all the extra code and funkiness required for commands (for example, SL apps needing to raise the ICommand.CanExecuteChanged event).  I prefer to use commands mainly when you need to pass a parameter to a ViewModel method, which is rare because View elements are generally bound to ViewModel properties.

There are several features included in the Simple MVVM Toolkit which appear to be lacking in MVVM Light. For example, the async support in MVVM Light is simply a wrapper over the Dispatcher, whereas Simple MVVM has async support built right into the ViewModel base class, which transparently marshals to the UI thread when firing the PropertyChanged event.  There is a Notify method for doing the same when communicating with the View using events.

Simple MVVM has two kinds of ViewModels: a general-purpose VM, good for showing summary lists and such, and a “detail’ VM, useful for binding a VM to a single model entity.  The ViewModelDetailBase class has a Model property which you can use to expose the model so that the View can bind directly to it.  This eliminates redundant code in the VM where you need to duplicate each and every model property. The detail VM base class also implements IEditableDataObject with deep cloning and allows you to associate VM properties with one or more model properties, so that updates to the model properties cascade to the associated VM property.

Lastly, Simple MVVM has direct support for dependency injection with MEF (Managed Extensibility Framework) and unit testing (for example with the Silverlight Unit Testing Framework).  In fact, there is an “injected” ViewModel locator item template that allows for mock service agents to be injected into ViewModels when executed by a unit test. The Simple MVVM RIA Services project template includes this code.

Implementation

There is a marked difference between the toolkits in terms of philosophy and style. MVVM Light emphasizes the use of a Messenger for loosely-coupled communication in just about all aspects of the app, including data binding, dialogs and navigation.  Simple MVVM, on the other hand, takes a more pragmatic approach by using events for communication between Views and the ViewModels they own.  The View already knows about its ViewModel, so I don’t see the justification for a message bus in the case of error messages or dialogs.  The VM simply exposes an event and the View subscribes to it, popping up a dialog if needing user input.  It can then communicate the result back to the VM by means of a callback on the event args that are passed in. Simple.

Simple MVVM, like MVVM Light, does include a MessageBus, but there is a different implementation.  MVVM Light allows for any kind of message token and has all kinds of message types – dialog, generic, notification (with and without callback), and property changed.  I chose a simpler approach, allowing only string tokens and a one message type: NotificationEventArgs (with or without callback), which is also used for event-based communication between Views and ViewModels.  The simplicity of this design is its strength: it is both easy to use and it encompasses every kind of communication you would want to perform.

Speaking of ease of use, the ViewModelBase class in Simple MVVM has helper methods for sending and receiving messages.  And the MessageBus uses a leak-proof eventing model, which means you never have to worry about unregistering with the MessageBus.  Subscribers are weakly referenced, so the MessageBus will not prevent them from being garbage collected, thereby avoiding a source of memory leaks. (Note: While the Messenger in v3 of MVVM Light has a bug that causes a memory leak if you fail to unregister, for v4 Laurent intends to use the same leak-proof eventing model as Simple MVVM.)

As you can see, there is a world of difference between the two toolkits, both in terms of design and the feature set, and also in terms of user support.  I designed my toolkit for a broad audience, targeted toward developers who are looking for a simple toolkit that is easy to learn and use, but one that also offers a rich feature set.  By deploying it with an installer (with auto updates from the VS Extensions Gallery and NuGet), documentation, samples and VS templates and snippets, I hope to have helped make your development experience with MVVM more productive and rewarding. Enjoy.

Posted in Technical | Tagged | 44 Comments

WCF RIA Services Webinar

I’m performing a free webinar today for DevelopMentor: Turbocharge Silverlight Development w/WCF RIA Services.  It’s taking place today, Wed April 20, 2011, at 3 pm pst, 11 pm bst.  Here’s the description:

Writing a full-fledged Rich Internet Application presents a number of
daunting challenges: forced n-tier, async, latency, validation, concurrency,
and authentication. WCF RIA Services simplifies and streamlines the process
with support for query composability, change-tracking and batch updates,
attributes for presentation and data validation, shared code and async
support. In this seminar Tony will pull back the curtain to show you how
RIA Services performs its magic, and he’ll provide tools and techniques to
reduce the time and effort required to build Silverlight business
applications.

You can download the slides and demos here: http://bit.ly/ria-webinar.

You can download the screencast recording for offline viewing on your pc or mobile device.

Posted in Technical | Tagged | 14 Comments

Screencast for Getting Started with Simple Mvvm Toolkit

I have just published the very first screencast for the Simple Mvvm Toolkit.  It shows you how to install the toolkit and use a Visual Studio project template to create a Silverlight MVVM app in just a few minutes. You’ll also learn how to use Visual Studio item templates installed by the toolkit, together with code snippets and xml snippets, to quickly build your own Models, Views and ViewModels.

gs-screencast

You can watch the screencast live, or download and watch it offline on your pc, iPhone, iPad or other device.

I used the screen capture tool, Camtasia, to record the screencast, which allowed me to add zooming to the recording, as well as transitions and other effects.  It also let me export the recording in mp4 format – I love to watch screencasts on my iPad – and upload it to screencast.com for live video streaming.  Instead of storing the 50 MB video file on my personal web site, I decided to upload it to Amazon’s S3 storage service.

Posted in Technical | Tagged | 1 Comment

Simple Mvvm Toolkit Version 2.0: Better and Even Easier to Use

I have just released version 2.0 of the Simple Mvvm Toolkit on CodePlex, NuGet and the Visual Studio Extensions Gallery.

smvvm-vsext

Now all you have to do to get it is open Visual Studio and select Extensions Manager from the Tool menu, then search for “Simple Mvvm Toolkit” and click the Download button.  Launch SimpleMvvmInstaller.exe and you’ll get the whole shebang: binaries, project and item templates, code snippets, samples and source code, copied to the SimpleMvvmToolkit directory in your Program Files folder.  The ReadMe.txt file lists all the prerequisites you’ll need to install before using the toolkit. The installer will even add the toolkit to Visual Studio’s referenced assemblies, so that it appears in the list of assemblies when you show the Add Reference Dialog.

smvvm-addref

Visual Studio integration is nice, but the killer feature of v2 is the new Visual Studio project templates. You heard right, the installer not only gives you the item templates and code snippets you had in v1, but it also provides four project templates: Silverlight, Windows Phone, WPF and RIA Services.  Each of these gives you a ready-made Visual Studio project that references the toolkit and includes Models, Views, ViewModels, ServiceAgents, and a ViewModelLocator.  All you have to do is open the included ReadMe.txt file and follow the simple instructions, using each of the provided classes as examples.  To get started just open Visual Studio, select File, New Project, then click on the Mvvm category beneath Windows (for WPF), Silverlight, or Silverlight for Windows Phone.

smvvm-proj

If you select, for example, the SimpleMvvmSilverlight template, you’ll get a brand new project with the following folder structure.

smvvm-sl

This is nice, but the amazingly awesome project template is SimpleMvvmRiaServices.

smvvm-ria

Selecting this template will give you three projects: a Silverlight app, a Web host (the Silverlight and Web projects have a RIA Services link), and a Test project.  [This, by the way, took a lot of effort to pull off.]  Press F5 and voila!  You have a fully functional Silverlight app with WCF RIA Services that uses the Simple MVVM Toolkit, including ViewModel-driven navigation with the MessageBus, event-based modal dialogs, entity persistence with CRUD operations, and unit testing with MEF-based dependency injection. Wow! From this point all you have to do is follow instructions in the ReadMe.txt files in each of the three projects and replace supplied classes with your own using the SimpleMvvm item templates and code snippets.  [NOTE: I intend to publish a screen cast showing you precisely how to do this.]

smvvm-riarun

If you set the Test project as the startup and hit F5, you’ll get a fully functional unit test application.  This is enabled by the supplied InjectedViewModelLocator (found in the Locators folder) and the ServiceAgentExport attribute placed on real and mock service agents.

smvvm-testrun

As you can see, v2 of the toolkit offers a lot in the way of productivity and ease-of-use.  But if you were to peek under the covers you’d discover even more simple goodness.  First, I have removed the use of a dictionary in the ViewModelLocator item templates and instead create ViewModels on-demand in property getters.  This involves a breaking change in the way you set the DataContext in Views.  There is no longer the need to insert square brackets around the ViewModel property in the Path.  This allows the View to control the lifetime of the ViewModel, avoiding a potential memory leak, but it also results in a lot less code in the locator when you use the mvvmlocator, mvvmlocatornosa (no service agent required) or mvvminjectedlocator (injected service agents) code snippets.

DataContext="{Binding Source={StaticResource Locator}, 
    Path=ItemListViewModel}"

In addition, the MessageBus is now implemented using a leak-proof eventing model, which removes the requirement to un-register for messages.  To simplify messaging even further, the ViewModelBase class now has two easy methods you can call: RegisterToReceiveMessages and SendMessage. (The only other breaking change in v2 is that you no longer use the MessageBus class directly.) Note that inter-ViewModel communication using the MessageBus is only required if you wish to perform navigation based on logic in a ViewModel, such as a Save method.

public class MainPageViewModel : ViewModelBase<MainPageViewModel>
{
    public MainPageViewModel()
    {
        this.RegisterToReceiveMessages(MessageTokens.Navigation, 
            OnNavigationRequested);
    }
}
public class CustomerViewModel : ViewModelBase<CustomerViewModel>
{
    public void Save()
    {
        SendMessage(MessageTokens.Navigation, 
            new NotificationEventArgs(PageNames.Home));
    }
}

Lastly, v2 adds Parts 2 and 3 to the Main sample application.  Part 2 walks you through features such as dependency injection, unit testing, messaging, property associations and long-running async operations.  Part 3 simply ports the application to WCF RIA Services and adds methods for saving batch changes (inserts, updates and deletes) in a single round-trip to the service.

Speaking of unit testing, one other thing to note is that the toolkit contains an extension method that makes it easier to perform async unit testing with the Silverlight Unit Testing Framework that ships as part of the Silverlight Toolkit.  Basically it adds a timeout to the EnqueueConditional method so that tests that fail don’t go on forever.

So there you have it! Version 2 of the Simple MVVM Toolkit is more robust and is even easier to use: an automated installer, Visual Studio project templates (including RIA Services), simplified locator and messaging APIs that protect you from memory leaks, and expanded end-to-end sample applications. Sweet.

Posted in Technical | Tagged | 17 Comments

Stay Up-to-date on Tony’s World

I just upgraded the sidebar on my blog to include a Subscribe widget, which you can click to get email notifications whenever new posts or comments appear on my blog.  In addition to showing a tag cloud, recent posts and recent comments, there is a section showing my recent tweets and a link to follow me on Twitter or Facebook.  I’m also showing my blog’s hit count, which is currently over 42,000 – wow!

  blog-sidebar1 blog-sidebar2 blog-sidebar3

There is also a way to get notified of new releases of my Simple MVVM Toolkit.

smvvm-sub1

smvvm-sub2

When you sign-in to CodePlex, you can click on the link under Release Notifications to get an email whenever I release a new version of the toolkit.

Enjoy!

Posted in Personal, Technical | Leave a comment

Building a Leak-Proof Eventing Model

One of the main features of the .NET Framework is to provide automatic memory management via garbage collection.  You might think this would solve the problem of memory leaks in managed applications, but the effectiveness of the garbage collector can be hampered by your code.  The GC will not release memory from objects that have root references, which can be local or static variables.  If you maintain these references, the GC will not collect them.  If you create more instances and keep references to them, memory consumption will continue to grow, resulting in a leaky application.

Note: You can download the code for this blog post here.

Sometimes it’s not so apparent exactly where you’re holding a reference.  This is the case with delegates, which are basically type-safe function pointers. If you fire up Reflector and take a look at a delegate definition, such as Action or EventHandler, you’ll see that the constructor takes two parameters.  The second is a native integer that basically points to the memory address of the target method.  But the first parameter is a System.Object pointing to the instance that owns the target method. (It’s set to null when pointing to a static method.)

public class System.EventHandler : Delegate
{
    public EventHandler(object @object, IntPtr method) { }
}

In other words, a reference to the delegate is actually a reference to the instance where the target method is defined.  If an event publisher holds the delegate reference, then you can’t simply set the subscriber instance to null and expect it to be garbage collected.  The best thing would be for the subscriber to unregister from the event before it gets disposed.  But that means having to implement IDisposable or, worse yet, implementing a finalizer.  This is error-prone and far from fool-proof.  Trust me, you don’t want to go there.

hard-del

What we need is a way for a publisher to expose an event while allowing subscribers to be garbage collected.  Enter the WeakReference, which is a reference that won’t prevent the referenced object from being garbage collected.  A publisher can weakly reference an event subscriber and only fire the event if the subscriber has not been garbage collected, which it can verify by checking the IsAlive property of the weak reference.

The question is, how do you get a reference to the subscriber’s delegate without referencing the delegate?  One idea is to have a weak reference to the delegate itself.  But this won’t work because there’s nothing to prevent the delegate from being garbage collected, even if the subscriber it points to is still alive.

weak-del

If the publisher weakly references the delegate and the delegate gets garbage collected, there’s no way for the publisher to fire the event.  If the publisher weakly references the subscriber, but maintains a hard reference to the delegate, the subscriber won’t be garbage collected when it needs to be, resulting in a potential memory leak.

One solution is for the publisher to weakly reference the subscriber and re-create the delegate when it needs to fire the event.  That way, the subscriber can be collected, because the publisher does not reference the delegate, but it can fire the target method by getting a pointer to it only if the subscriber is still alive.

create-del

Here is what that code would look like:

// Note: Don’t use this code with Silverlight
class WeakDelegate
{
    private readonly WeakReference subscriber;
    private readonly string methodName;
    private readonly Type delegateType;

    public WeakDelegate(Delegate targetMethod)
    {
        this.subscriber = new WeakReference(targetMethod.Target);
        this.methodName = targetMethod.Method.Name;
        this.delegateType = targetMethod.GetType();
    }

    public bool IsAlive
    {
        get { return subscriber != null && subscriber.IsAlive; }
    }

    public Delegate GetDelegate()
    {
        if (IsAlive)
        {
            return Delegate.CreateDelegate(delegateType, 
                subscriber.Target, methodName);
        }
        return null;
    }
}

In full .NET (and consequently WPF) this code works like a charm.  However, if you were to try it on Silverlight or Windows Phone, you’ll soon be banging your head against a wall (at least figuratively).  Those flavors of .NET put some restrictions on Delegate.CreateDelegate.  First of all, the target method needs to be public or you’ll get a MethodAccessException.  It has to be of form Action or Action<T> or you’ll get a MissingMethodException.  It has to be an instance method or you’ll get either a MissingMethodException or an ArgumentException. Yikes!

While it may seem like we’re between a rock and a hard place, there is a solution.  The key is for the publisher to use a proxy to fire events on its behalf.  The proxy, which has delegates referencing the subscriber, is referenced weakly by the publisher and strongly by the subscriber.  The subscriber can be garbage collected because the delegate pointing to it is only referenced by the subscriber itself.  Because the subscriber has a reference to the publisher proxy, the delegate won’t be garbage collected until the subscriber is. Best of all, this approach works across the board with full .NET / WPF, Silverlight and Windows Phone. Yay!

proxy-del

So what does the code look like for this pattern?  First, we will need an interface that contains events that the subscriber can subscribe to.  We’ll call it IPublisher.

interface IPublisher
{
    event EventHandler SomeEvent;
}

Notice we’re exposing an event of type EventHandler.  This is just an example.  You can expose any number of events that suit your fancy, including various forms of EventHandler<T>.  For illustration purposes I’m trying to keep it simple.  The subscriber accepts an IPublisher to its constructor so that it can subscribe to the event as it normally would.

class Subscriber
{
    IPublisher publisher;

    public Subscriber(IPublisher publisher)
    {
        this.publisher = publisher;
        publisher.SomeEvent += OnSomeEvent;
    }

    private void OnSomeEvent(object sender, EventArgs e)
    {
        Console.WriteLine("SomeEvent was fired");
    }
}

There’s nothing unusual here.  Now for the publisher proxy.  For that we’ll need another interface: IPublisherProxy, which extends IPublisher by adding a method that fires the event.  If you added more events to IPublisher, you would add corresponding methods to IPublisherProxy to fire those events.

interface IPublisherProxy : IPublisher
{
    void FireEvent(object sender, EventArgs e);
}

The subscriber needs to expose an IPublisherProxy to the publisher, so that it can weakly reference it and also call FireEvent.  For that we need yet another interface that has a property of type IPublisherProxy.  We’ll call it ISubscriber.

interface ISubscriber
{
    IPublisherProxy PublisherProxy { get; }
}

The subscriber will need to implement this interface and maintain a hard reference to the publisher proxy so that it will only be garbage collected when the subscriber is GC’d.  Implementing it explicitly will be cleaner because only the publisher is interested in it.

class LeakProofSubscriber : ISubscriber
{
    IPublisher publisher = null;

    public LeakProofSubscriber(IPublisher publisher)
    {
        // Subscribe to events
        this.publisher = publisher;
        this.publisher.SomeEvent += OnSomeEvent;
    }

    // Explicitly implement IPublisherProxy
    IPublisherProxy publisherProxy = new PublisherProxy();
    IPublisherProxy ISubscriber.PublisherProxy
    {
        get { return publisherProxy; }
    }

    private void OnSomeEvent(object sender, EventArgs e)
    {
        Console.WriteLine("SomeEvent was fired");
    }
}

Now the fun begins: building a leak-proof publisher.  First we’ll need a List<WeakReference> with weakly referenced publisher proxies.  Then, in order to add proxies, we implement the event manually by providing our own add and remove constructs.  The compiler simply translates these to Add and Remove methods that accept a delegate.  We’ll pull out the subscriber from the Target property of the delegate, cast it to ISubscriber, read the PublisherProxy property, then add or remove the incoming delegate to its event.  Lastly, we’ll add or remove the proxy from our list of weak references.  When we want to fire the event, we simply check to see if the proxy is alive and then call FireEvent.

class LeakProofPublisher : IPublisher
{
    // List of weakly referenced proxies
    private List<WeakReference> weakProxies 
        = new List<WeakReference>();

    // Subscribers to add and remove themselves from subscriptions
    public event EventHandler SomeEvent
    {
        add
        {
            // Get subscriber
            ISubscriber subscriber = value.Target as ISubscriber;
            if (subscriber != null)
            {
                // Add handler to proxy
                IPublisherProxy proxy = subscriber.PublisherProxy;
                proxy.SomeEvent += value;

                // Add to list of weakly referenced proxies
                weakProxies.Add(new WeakReference(proxy));
            }
        }
        remove
        {
            // Get subscriber
            ISubscriber subscriber = value.Target as ISubscriber;
            if (subscriber != null)
            {
                // Remove handler from proxy
                IPublisherProxy proxy = subscriber.PublisherProxy;
                proxy.SomeEvent -= value;

                // Remove from list of weakly referenced proxies
                for (int i = weakProxies.Count - 1; i >= 0; i--)
                {
                    var weakProxy = weakProxies[i];
                    var existing = GetProxy(weakProxy);
                    if (existing != null && 
                        object.ReferenceEquals(existing, proxy))
                        weakProxies.Remove(weakProxy);
                }
            }
        }
    }

    // Ask proxy to fire event
    public void FireEvent()
    {
        foreach (var weakProxy in weakProxies)
        {
            var proxy = GetProxy(weakProxy);
            if (proxy != null)
            {
                proxy.FireEvent(this, EventArgs.Empty);
            }
        }
    }

    private IPublisherProxy GetProxy(WeakReference weakProxy)
    {
        if (weakProxy != null && weakProxy.IsAlive)
        {
            IPublisherProxy proxy = weakProxy.Target 
                as IPublisherProxy;
            if (proxy != null)
            {
                return proxy;
            }
        }
        return null;
    }
}

There you go!  I didn’t say the solution would be easy, but the problem is solvable.  The nice part is that, while the publisher does the heavy lifting, the only extra code that the subscriber needs is the PublisherProxy property.  However, because we implement it explicitly, it doesn’t pollute the subscriber’s appearance.  You can download the full source code here.

Although I wouldn’t recommend making all your events leak-proof in this manner, there are scenarios where making events leak-proof is an essential requirement.  An example would be a message bus (also called an event aggregator or event mediator), which I’ve incorporated into my Simple MVVM Toolkit (version 2 will support leak-proof events and drop the requirement to unregister for messages).  You wouldn’t want subscribers to not get garbage collected simply because they registered to received messages and failed to unregister.

As you can see, weak events can be a thorny problem to solve.  Hopefully this approach will help if you have the need for them.  Happy coding!

Posted in Technical | Tagged , , | 11 Comments

Simple MVVM Toolkit: Ready for RIA Services

Part of Microsoft’s Silverlight strategy is to position it as a platform for building rich line of business applications.  One reason for this is the deployment story: in or out of the browser on Windows, Mac or Linux.  Another is the availability of WCF RIA Services, which eases n-tier application development for Silverlight by providing advanced features such as query composability, change-tracking and transactional batch updates, end-to-end data validation, better handling of async operations, application security with support for both authentication and authorization.  (For more information see my blog post and presentation of RIA Services.)

NOTE: You can obtain the code for this blog post from the SimpleMvvm-RiaServices sample project that’s part of the download for my Simple Mvvm Toolkit.

So how well does RIA Services play with MVVM?  Very nicely, I am happy to say.  In fact, you can easily use my Simple MVVM Toolkit to build a Silverlight app that uses RIA Services.  All you have to do is create a ServiceAgent that uses the generated DomainContext class to load and persist entities from the RIA Services web app.

Developing a Silverlight app that uses RIA Services is fairly straightforward.  You can start either with a plain vanilla Silverlight app by selecting the “Silverlight Application” Visual Studio project template, or you can choose the “Silverlight Business Application” template, which is based on the “Silverlight Navigation Application” template and has a few more bells and whistles (mainly user membership and authentication).  I suggest you start with a basic project template and then move on to the business application template when you want to explore features related to application security.

sl-app-dialog

After clicking OK you’ll be presented with another dialog in which you specify a web project to host your Silverlight app and if you wish to enable WCF RIA Services.  You should probably go ahead and check the box to enable RIA Services, but you can add a RIA Services link later on if you wish.

enable-ria

Now you have to decide where you want to get your data from.  Most of the time that would be from a database using the Entity Framework.  But to keep it simple we’ll just create some in-memory objects and expose them over RIA Services.  The important point to keep in mind here is that RIA Services is not in any way wedded to Entity Framework – you can use another ORM (such as NHibernate) or none at all.

Let’s say we create a Customer class with three properties: CustomerId, CustomerName and City.  Then for convenience we’ll add a factory method to return a List of them.  To play nice with RIA, you will need to add a [Key] attribute to one of the properties in Customer, such as CustomerId.

public class Customer
{
    [Key]
    public int CustomerId { get; set; }
    public string CustomerName { get; set; }
    public string City { get; set; }

    public static List<Customer> GetCustomers()
    {
        return new List<Customer>
        {
            new Customer { CustomerId = 1, 
                CustomerName = "Bill Gates", City = "Redmond" },
            new Customer { CustomerId = 2, 
                CustomerName = "Steve Jobs", City = "Cupertino" },
            new Customer { CustomerId = 3, 
                CustomerName = "Mark Zuckerberg", City = "Palo Alto" }
        };
    }
}

Next create a CustomerDomainService class using the Domain Service Class item template.

domain-service

Then add a GetCustomers method and return an IQueryable<Customer> by calling Customer.GetCustomers and invoking AsQueryable on the result.  IQueryable signifies that you are returning a query that can be further refined with things like filters or sorting.

[EnableClientAccess()]
public class CustomerDomainService : DomainService
{
    // Will surface as a method on the client DomainContext
    public IQueryable<Customer> GetCustomers()
    {
        return Customer.GetCustomers().AsQueryable<Customer>();
    }
}

When you build the project, RIA Services will project a CustomerDomainContext class on the client (it’s hiding inside the Generated_Code folder that’s visible only when you show all files).  There you have a GetCustomersQuery method that calls the GetCustomers service method and returns, you guessed it, an IQueryable<Customer>.

Now that you’ve done the RIA Services bit, it’s time to put in MVVM pieces in place.  For that you follow the instructions I’ve laid out in the Getting Started guide for the toolkit.  (The SimpleMvvm-RiaServices sample also has a readme file with step-by-step instructions.)  The key difference is that the ServiceAgent implementation will load entities from the query returned by CustomersDomainContext.GetCustomersQuery.

First create an ICustomerServiceAgent interface with a GetCustomers method.  Note that the method signature should reflect the asynchronous nature of services in Silverlight, with a callback parameter that returns either a sequence of customers or an exception.

public interface ICustomerServiceAgent
{
    void GetCustomers(Action<IEnumerable<Customer>, 
        Exception> completed);
}

The implementation looks like this.

public void GetCustomers(Action<IEnumerable<Customer>, 
    Exception> completed)
{
    // Load GetCustomersQuery
    EntityQuery<Customer> query = _domainContext.GetCustomersQuery();
    _domainContext.Load(query, loadOp =>
        {
            // Declare error and customers
            Exception error = null;
            IEnumerable<Customer> customers = null;

            // Set error or customers
            if (loadOp.HasError)
            {
                error = loadOp.Error;
            }
            else
            {
                customers = loadOp.Entities;
            }

            // Invoke completion callback
            completed(customers, error);
        }, null);
}

The code looks a little bit funny at first, because you have to call Load on an EntityQuery<Customer>, passing a callback method in which you harvest the result, which is an IEnumerable<Customer>.  The ViewModel simply invokes the ServiceAgent’s GetCustomers method, perhaps creating an ObservableCollection<Customer> for binding to a grid.

public void GetCustomers()
{
    serviceAgent.GetCustomers(GetCustomersCompleted);
}

private void GetCustomersCompleted(IEnumerable<Customer> result, 
    Exception error)
{
    // Notify view of an error
    if (error != null)
    {
        NotifyError("There was an error retrieving customers", error);
    }
    // Set Customers property
    else
    {
        this.Customers = new ObservableCollection<Customer>(result);
    }
}

If you have a DataGrid with an ItemsSource bound to the ViewModel Customers property, you should see the results displayed like so.

customers-grid

Now you have an Silverlight MVVM application that uses WCF RIA Services! The nice thing is that you can use the Simple MVVM Toolkit as is with RIA Services.  The ServiceAgent already abstracts away the task of retrieving entities, and the ViewModel doesn’t really care how it happens.  From the perspective of the ViewModel, RIA Services is simply an implementation detail. Nice.

Posted in Technical | Tagged , | 15 Comments

Simple MVVM Toolkit: Unit Testing with Dependency Injection and MEF

One of the main benefits of using the MVVM (Model, View, ViewModel) design pattern is to support better testability.  Having to click through screens to test an application can be tedious and time-consuming, and it may not provide good code coverage or regression testing.  By abstracting the View into a separate ViewModel, you can independently test the ViewModel to make sure it behaves as expected.  The unit testing framework is simple another consumer of the View-Model.  In fact, thinking about the testability of ViewModels can help remind you to keep visual elements, such as brushes and dialogs, out of the ViewModel.

NOTE: You can obtain the code for this blog post from the SimpleMvvm-Injection sample project that’s part of the download for my Simple Mvvm Toolkit. Support for DI in the toolkit is explained in the online documentation.

Whether or not you subscribe to the tenants of Test-Driven Development (TDD), you should test your ViewModels without any dependency on WCF services or databases.  This keeps the tests simple, focused and fast.  That doesn’t mean you will not want to also perform “integration tests” by connecting to live services that retrieve and persist real data.

What this means is that you need a mechanism for switching back and forth between real and mock data sources depending on whether you are performing unit or integration tests.  Enter Dependency Injection!  DI (sometimes referred to as IoC, or Inversion of Control) provides a way to create different sets of objects depending on what you are doing.  There are a number of DI containers out there, including Unity (MS Patterns) and Ninject, and Windsor.

The problem I find with adopting one of these is that, while each offers a number of bells and whistles, they may be overkill when all you want to do is enable unit testing for your MVVM app.  This is where Managed Extensibility Framework (MEF) comes in.  The nice thing about MEF is that it comes with .NET 4.0 and Silverlight right out of the box and is focused on the simple task of providing instances based on an agreed-upon contract.  (For a complete explanation of MEF see my blog post and screencast.)

The good news is that you don’t have to completely grok MEF in order to take advantage of it.  That’s because I’ve incorporated MEF into my Simple MVVM Toolkit to support DI for unit testing.  When creating an app using the toolkit, add an “Injected” ViewModel Locator using the supplied Visual Studio item template.

injected-locator

What you get is a class that maintains a dictionary of ViewModels, each constructed by supplying a service agent, whose job it is to supply data to the ViewModel.  To support testing, you’ll want two service agents, one using mock data and the other using real data, each of which implements a common interface.  For example, an ICustomerServiceAgent might have a method called GetCustomer, with a customerId parameter, as well as a completion callback that returns either a Customer or an Exception.

public interface ICustomerServiceAgent
{
    void GetCustomer(int customerId, 
        Action<Customer, Exception> completed);
}

Both RealCustomerServiceAgent and MockCustomerServiceAgent classes implement this interface, with the real service agent invoking a WCF service operation to obtain the customer from a database, and the mock service agent providing a fabricated customer.  Notice that the interface supports asynchronous operations.  This means that the mock service agent would use a BackgroundWorker component to fake an async service call.

public class MockCustomerServiceAgent : ICustomerServiceAgent
{
    public void GetCustomer(int customerId, 
        Action<Customer, Exception> completed)
    {
        // Use background worker to simulate async operation
        var bw = new BackgroundWorker();

        // Handle worker started
        bw.DoWork += (s, ea) =>
        {
            // Create a new customer
            Thread.Sleep(TimeSpan.FromSeconds(2));
            ea.Result = new Customer
            {
                Id = (int)ea.Argument,
                Name = "John Doe",
                CustomerType = CustomerType.Mock
            };
        };

        // Hander worker completed
        bw.RunWorkerCompleted += (s, ea) =>
        {
            if (ea.Error != null)
            {
                completed(null, ea.Error);
            }
            else
            {
                completed((Customer)ea.Result, null);
            }
        };

        // Start async operation
        bw.RunWorkerAsync(customerId);
    }
}

The Injected ViewModel Locator uses MEF to supply either a real or mock service agent, depending on an attribute you attach to each service agent.  The ServiceAgentExport attribute is defined in the toolkit library and has two parameters: the type of the service agent interface, and an AgentType enum, which has values for Unspecified, Real and Mock.  Here’s what the MockCustomerServiceAgent looks like with the MEF export attribute and an AgentType.Mock parameter.

[ServiceAgentExport(typeof(ICustomerServiceAgent), 
    AgentType = AgentType.Mock)]
public class MockCustomerServiceAgent : ICustomerServiceAgent
{

This lets the ViewModel locator know that this is a mock service agent.  The real service agent has the same attribute, but with an AgentType.Real attribute parameter.

[ServiceAgentExport(typeof(ICustomerServiceAgent), 
    AgentType = AgentType.Real)]
public class RealCustomerServiceAgent : ICustomerServiceAgent
{

After adding an injected ViewModel locator to the project, you will see a number of TODO items.  Basically, you need to specify the service agent interface and flesh out a ServiceAgents property which specifies kind service agent you want to use.

public class InjectedViewModelLocator
{
    // View model dictionary
    private Dictionary<string, ViewModelBase> viewModels =
        new Dictionary<string, ViewModelBase>();

    // Add a member for ICustomerServiceAgent
    private ICustomerServiceAgent serviceAgent;

    // Specify default service agent type
    private AgentType agentType = AgentType.Real;

    [ImportMany]
    public Lazy<ICustomerServiceAgent, IServiceAgentMetadata>[] 
        ServiceAgents
    {
        set
        {
            var lazy = (from sa in value
                        where sa.Metadata.AgentType == agentType
                        select sa).FirstOrDefault();
            if (lazy != null) serviceAgent = lazy.Value;
        }
    }

If you’re not familiar with MEF, this may appear somewhat confusing, because the ServiceAgents property only has a setter and is an array of Lazy<T, TMetadata>.  What we’re doing here is simply asking MEF to give us one or more ICustomerServiceAgents.  What the Lazy type does is defer creation of the class implementing ICustomerServiceAgent until we access the Value property, which we only do if the AgentType matches what we’ve set for the agentType field.  In other words, we will set serviceAgent to either RealCustomerServiceAgent or MockCustomerServiceAgent, depending on whether we set agentType to Real or Mock.  This is not done until you call CompositionInitializer.SatisfyImports, which takes place in the locator’s ctor.

public InjectedViewModelLocator()
{
    // Use MEF to inject service agents
    CompositionHost.Initialize(new DeploymentCatalog());
    CompositionInitializer.SatisfyImports(this);

    // Throw exception if service agent not initialized
    if (serviceAgent == null)
    {
        throw new Exception("Service agent not initialized");
    }

    // Call AddCustomerViewModel methods passing serviceAgent
    AddCustomerViewModel(serviceAgent);
}

The reason why we’re going to all this trouble is to be able to test the ViewModel.  For that we’ll leverage the Silverlight Unit Testing Framework, which ships with the Silverlight Toolkit.  We add a new project to the solution by selecting the Silverlight Unit Test Application project template.

sl-test

What we get is a project containing a test class.  Because our service calls are asynchronous, we need to derive the class from SiverlightTest, add an Asynchronous attribute to the test method, and call the EnqueueTestComplete method in the completion callback.

[TestClass]
public class CustomerViewModelTest : SilverlightTest
{
    [TestMethod, Asynchronous]
    public void CreateCustomerTest()
    {
        // Create a view-model locator
        InjectedViewModelLocator locator = 
            new InjectedViewModelLocator();
        locator.AgentType = AgentType.Mock;

        // Get the customer view model
        var vm = locator["CustomerViewModel"] as CustomerViewModel;
        Assert.IsNotNull(vm);

        // Handle error
        vm.ErrorNotice += (s, ea) =>
        {
            // Fail the test showing the error message
            Assert.Fail(ea.Data.Message);

            // Signal we're done
            EnqueueTestComplete();
        };

        // Handle property changed
        vm.PropertyChanged += (s, ea) =>
        {
            if (ea.PropertyName == "Model")
            {
                // Take a look at the customer
                Customer customer = vm.Model;
                Assert.IsNotNull(customer);
                Assert.Equals(customer.Name, "John Doe");

                // Signal we're done
                EnqueueTestComplete();
            }
        };

        // Use vm to create a customer
        vm.CreateCustomer();
    }
}

To perform the test you have to actually run the test project – unlike traditional uniting testing in Visual Studio.  When you do so, you’ll see the test results displayed in the browser.

test-result

Have fun!

Posted in Technical | Tagged , , | 2 Comments

Climb Onboard on the MVVM Message Bus

In a previous post I blogged on various ways to tackle the problem of showing dialogs in an MVVM application. There I advocated using events as a communication mechanism.  The ViewModel fires an event; the View can subscribe to the event and respond in a way that interacts with the user, which could be by displaying a dialog.  It is important to avoid showing dialogs or other visuals directly from the ViewModel in order to maintain the separation of concerns that is the raison d’etre of MVVM and which produces benefits such as better maintainability and testability.

It is possible to use events for communication between View and ViewModel because the View has a direct reference to the ViewModel and can therefore subscribe to events on the ViewModel.  But what about when you want one ViewModel to communicate with another ViewModel?  While you might be tempted to create a direct reference between ViewModels, the result would be a tight coupling that can make the app structure more brittle and harder to maintain.  While this may seem innocent enough at first, over time you can end up with spaghetti code.  To take the pasta analogy a step further, what MVVM tries to do is provide better maintainability by separating the app into layers, like lasagna.  If you have ViewModels referencing one another, you’re introducing spaghetti back into the recipe and will end up with bad case of indigestion.

A classic way to address this problem is by funneling inter-ViewModel communication through a mediator, also called an event aggregator or message bus.  This is why I incorporated a MessageBus class into my Simple MVVM Toolkit.  It has a Register method, which accepts a string token and a method to callback when someone sends a message to the bus using the specified token.  There is also an Unregister method you can call when you no longer wish to receive messages (make sure to call this when doing clean-up in your ViewModel’s Dispose method).  More than one ViewModel can register to receive messages, which are broadcast to subscribers in a fire-and-forget manner.  The Notify method will transparently marshal the call to the UI thread, while BeginNotify will invoke the subscriber’s method on a Thread Pool thread (for non-UI operations).

The payload of a message is the NotificationEventArgs class, which is also used for event-based communication between Views and ViewModels.  The nice thing about this class is that it overloaded constructors that accept a TOutgoing type argument, so you can pass any object in a strongly-typed manner, as well as a TIncoming argument for passing data from the message recipient back to the sender, for loosely-coupled two-way communication via the MessageBus.

A great example where the MessageBus comes in handy is application navigation that is driven by logic in a ViewModel. Typically the MainPage View will contain a navigation Frame element with its Source property bound to a property on its ViewModel that is of type Uri.  When the ViewModel sets this property, displays the desired page in the frame, usually with the assistance of a UriMapper.

nav-app

<navigation:Frame x:Name="ContentFrame" 
    Style="{StaticResource ContentFrameStyle}" 
    Source="{Binding Path=SelectedPage, Mode=TwoWay}" 
    Navigated="ContentFrame_Navigated" 
    NavigationFailed="ContentFrame_NavigationFailed">
    <navigation:Frame.UriMapper>
        <uriMapper:UriMapper>
        <uriMapper:UriMapping Uri="" 
            MappedUri="/Views/Home.xaml"/>
        <uriMapper:UriMapping Uri="/{pageName}" 
            MappedUri="/Views/{pageName}.xaml"/>
        </uriMapper:UriMapper>
    </navigation:Frame.UriMapper>
</navigation:Frame>

Notice the three hyperlink buttons sitting on the main page.  Each has a Command property that is bound to a NavigateCommand property on the ViewModel.  For the CommandParameter each passes the name of a View.  All the Navigate command does is set the SelectedPage property to a Uri constructed using the name of the passed-in page name.

<HyperlinkButton x:Name="customerLink"
    Style="{StaticResource LinkStyle}" 
    Command="{Binding Path=NavigateCommand}"
    CommandParameter="CustomerView"
    TargetName="ContentFrame" Content="customer"/>
private void Navigate(string pageName)
{
    Uri pageUri = new Uri("/" + pageName, UriKind.Relative);
    this.SelectedPage = pageUri;
}

So far, none of this requires communication between two different ViewModels.  But what if you wanted to navigate to a particular page based on logic in a ViewModel shown in the navigation frame.  For example, on the CustomerView you have a Save button, which when clicked will cause the Home page to be displayed in the navigation frame on the main page.  To accomplish this feat you would want to send a message from the CustomerViewModel to the MainPageViewModel with the name of the page to display.  Enter the MessageBus!

public void Save()
{
    MessageBus.Default.Notify(MessageTokens.Navigation, this,
        new NotificationEventArgs(PageNames.Home));
}

The Notify method passes a message token string, which is defined as a constant in the MessageTokens class.  Message senders and subscribers simply agree on the token used to exchange messages.  Also passed in the name of the page we want to navigate to, which in this case is the Home page.

In the constructor of the MainPageViewModel we subscribe to receive messages for the Navigation message token by calling the Register method on the MessageBus and passing both the token and a callback method, which is an EventHandler<NotificationEventArgs>.

public MainPageViewModel()
{
    MessageBus.Default.Register(MessageTokens.Navigation, 
        OnNavigationRequested);
}

void OnNavigationRequested(object sender, NotificationEventArgs e)
{
    Navigate(e.Message);
}

Notice that the callback method simply calls Navigate passing e.Message, which was set by the CustomerViewModel to be the name of the Home page (which happens to be “Home”).  Pretty cool, eh?

So there you have it.  You can download the sample Mvvm Navigation app as part of my Simple Mvvm Toolkit.  Also included is a Messaging sample app that demonstrates multicast and two-way messaging.  Enjoy.

Posted in Technical | Tagged | 20 Comments