Build a Multi-Project Visual Studio Template

Download the code for this article here.

Earlier this year I authored an open-source toolkit, called Simple MVVM Toolkit, to help developers build Silverlight, WPF and Windows Phone applications based on the Model-View-ViewModel design pattern. To enhance developer productivity, the toolkit combines a set of helper classes with code and xml snippets, as well as Visual Studio item and project templates. After installing the toolkit, all a developer needs to do to get started is open Visual Studio and create a new project by selecting one the project templates that appear under the Mvvm category.

  smvvm-proj

Visual Studio makes it extremely easy to create a single-project template. Simply select Export Template from the File menu and follow the prompts. This will produce a .zip file containing the contents of the project and a .vstemplate text file with xml describing the template content and properties.

exp-template

There are times, however, when it you would like to create a template which generates multiple projects belonging to a single Visual Studio solution. A good example is the SimpleMvmRiaServices project template shown in the first screenshot, which generates a Visual Studio solution with three projects: an ASP.NET Web project, a Silverlight client project, and a Test project for unit tests.  To create this template I first had to create individual templates for each of the three projects, then extract the contents of each zip file in order to combine them into a single multi-project Visual Studio template, with a .vstemplate file describing the contents.  Here is an example of a VSTemplate file I created for a Multi-Project WCF REST Template I recently did for a talk I gave at a .NET developer group (some of the content has been elided for clarity).

<VSTemplate Type="ProjectGroup">
  <TemplateData>
    <Name>WCF REST Service</Name>
    <Description>REST Service Template by Tony Sneed</Description>
    <ProjectType>CSharp</ProjectType>
    <TemplateGroupID>WCF</TemplateGroupID>
    <RequiredFrameworkVersion>4.0</RequiredFrameworkVersion>
  </TemplateData>
  <TemplateContent>
    <ProjectCollection>
      <ProjectTemplateLink ProjectName="$safeprojectname$.Client">
        Client\Client.vstemplate
      </ProjectTemplateLink>
      <ProjectTemplateLink ProjectName="$safeprojectname$.Entities">
        Entities\Entities.vstemplate
      </ProjectTemplateLink>
      <ProjectTemplateLink ProjectName="$safeprojectname$.Service">
        Service\Service.vstemplate
      </ProjectTemplateLink>
      <ProjectTemplateLink ProjectName="$safeprojectname$.Web">
        Web\Web.vstemplate
      </ProjectTemplateLink>
    </ProjectCollection>
  </TemplateContent>
  <WizardExtension>
    <Assembly>RestTemplateWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c9a76f51a8a9555f</Assembly>
    <FullClassName>RestTemplateWizard.RootWizard</FullClassName>
  </WizardExtension>
</VSTemplate>

The template encompasses four project templates: Client, Entities, Service and Web. Notice the variable, $safeprojectname$, which captures what the user entered for the project name in the New Project dialog. There is also a WizardExtension element, which references an IWizard implementation.  IWizard allows you to control the template creation process, for example, to allow projects to reference one another or to set project properties, such as the RIA Service project link required for my SimpleMvvmRiaServices template.

For my WCF REST template I wanted the Client and Service projects to both reference the Entities project, and for the Web project to reference the Service project. The problem here is that within each child template, $safeprojectname$ represents the current project name. There needs to be a way to pass in the root $safeprojectname$ from the parent template.  This is where the IWizard project comes in.

Start by creating a class library project and referencing the assembly, Microsoft.VisualStudio.TemplateWizardInterface.dll.  Create a RootWizard class that implements IWizard.  In the RunStarted method you can capture $safeprojectname$ from replacementParameters and store it in a public static Dictionary<string,string> so that it can be captured by a ChildWizard class and stored as $saferootprojectname$ in replacementParameters.

public class RootWizard : IWizard
{
    // Use to communicate $saferootprojectname$ to ChildWizard
    public static Dictionary<string, string> GlobalDictionary =
        new Dictionary<string,string>();

    // Add global replacement parameters
    public void RunStarted(object automationObject, 
        Dictionary<string, string> replacementsDictionary, 
        WizardRunKind runKind, object[] customParams)
    {
        // Place "$saferootprojectname$ in the global dictionary.
        // Copy from $safeprojectname$ passed in my root vstemplate
        GlobalDictionary["$saferootprojectname$"] = replacementsDictionary["$safeprojectname$"];
    }

    // Other members elided for clarity
}
public class ChildWizard : IWizard
{
    // Retrieve global replacement parameters
    public void RunStarted(object automationObject, 
        Dictionary<string, string> replacementsDictionary, 
        WizardRunKind runKind, object[] customParams)
    {
        // Add custom parameters.
        replacementsDictionary.Add("$saferootprojectname$",
            RootWizard.GlobalDictionary["$saferootprojectname$"]);
    }

    // Other members elided for clarity
}

You can now edit project references in child project csproj files, as well as using directives in source code files, to include $saferootprojectname$ where you want the user-entered project name to appear.

<Project ToolsVersion="4.0" DefaultTargets="Build">
  <ItemGroup>
    <ProjectReference Include="..\$saferootprojectname$.Entities
          \$saferootprojectname$.Entities.csproj">
      <Project>{3EC4AE2B-892C-42FC-9814-D46EB06A22E4}</Project>
      <Name>Entities</Name>
    </ProjectReference>
  </ItemGroup>
</Project>
using System;
using $saferootprojectname$.Entities;

namespace $safeprojectname$
{
    class Program
    {
        static void Main(string[] args)
        {
            // Client code goes here ...
        }
    }
}

Next, make sure to sign your wizard assembly, using a test certificate if you like, and then obtain the public key token by opening a Visual Studio command prompt at the location of your wizard dll and entering the command (replace WizardAssembly with your dll file name):
sn –T WizardAssembly.dll

sn-pubkey

Now that you’ve created a multi-project Visual Studio template, you need a way to deploy it.  The best way is to create a VSIX project, which allows you easily publish your template to the Visual Studio Extensions Gallery, so that developers from around the world can install it by selecting Extension Manager from the Tools menu right from within Visual Studio! First you’ll need to install the Visual Studio 2010 SP1 SDK (assuming you’ve first installed SP1 for VS 2010). Then create a new VSIX project (in the Extensibility category that now appears in the New Project dialog).  What you get is a nice designer for editing the .vsixmanifest file, where you can set properties and add content.

vsix-1

There are two items you will want to add as content. One is the template wizard assembly you just created, and the other is a zip file containing the multi-project template contents, including both the parent .vstemplate file and icons, as well as a folder for each child project template containing the project contents and .vstemplate file.

vsix-2

The important thing to note here is that the assembly for the IWizard implementation need not be installed into the Global Assembly Cache when it is packaged into the same VSIX project as the templates using it.  Another thing you might want to do when adding the template zip file is specify the category under which you want your template to appear in the Visual Studio New Project dialog.  In the the case of my WCF REST Template, I have indicated it should appear under the WCF category.

add-content

When you build the extensibility project, you’ll get a .vsix file that you can upload to the Visual Studio Extensions Gallery, so that it will appear in the Online Gallery when developers select Extension Manager from the Tools menu.  Enjoy.

ext-gallery

You can download the code for this article here.

Tony Sneed
http://blog.tonysneed.com

Posted in Technical | Tagged , | 11 Comments

Digging into WCF REST

Update: The recording for this talk is now available.

Last Thursday evening I presented a talk to the Dallas .NET User Group on support in WCF 4 for building REST-ful services. Here is a summary of the talk:

To REST or Not To REST? – Building REST-ful Services with the WCF Web Programming Model
REST is defined as an architectural style for building services that embrace the principles of the web. But what’s it good for? Tony will provide concrete examples of where it makes sense to implement REST-ful web services. He’ll also get down and dirty using the WCF Web Programming Model and show how WCF makes it easy to serve up POX or JSON, increasing the reach of your services to clients that don’t understand or care about SOAP. We’ll also look at API’s for syndicating content using RSS and ATOM.

Here are the slides and code for the talk, which highlighted improvements in WCF’s support for REST that arrived with .NET 4.0 and Visual Studio 2010, folding in features we first saw in the REST Starter Kit, which is now largely obsolete.

Here are some essential resources on WCF REST:

One of the things I highlighted in the talk is a Visual Studio template, which you can download from the Visual Studio Extensions Gallery, that creates a WCF REST-based service.  However, after installing the template, I was somewhat disappointed.  It creates a Visual Studio solution with just a single web project.  The service contract is merged with the implementation (just a class with no separate interface), and there is no client project.

About an hour before the talk, I decided to create my own version of the WCF REST Template, which creates a multi-project solution containing a web project with the service interface and class placed in a separate class library project and the entities in their own class library project.  I also threw in a console client project which consumes the WCF REST service and uses LINQ to XML to parse the results.  I was so pleased with the template, that I packaged it into a vsix project and uploaded it to the Visual Studio Extensions Gallery, so all you have to do is open up Visual Studio, go to Tools, Extension Manager, select Online Gallery and search for WCF REST Template.

ext-gallery

After installing the template, simply create a new project in Visual Studio, select the WCF category, and choose “WCF REST Service” from the list of project templates.

new-project

This will give you a solution containing four projects: An Entities project, containing a SampleItem class, a Service project, with an ISampleService interface implemented by a SampleService class, a Web project to host the service (which has a ReadMe file) and a Client project to consume the service.

sol-ex

All you have to do is set the Web project as the startup project for the solution and press Ctrl+F5 to launch the VS dev web server. Then set the Client project as the startup project and run it by pressing Ctrl+F5.  The client will issue an HTTP GET request to the service to retrieve XML representing a list of sample items. It uses LINQ to XML to parse the result into a list of items.

One of the things featured by the template is WCF 4’s simplified configuration model.  If you take a look at web.config, you’ll see that a default web http endpoint is configured to support a help page as well as automatic format selection (XML or JSON) based on the Content-Type and/or Accept HTTP headers.

rest-help

Typing the sample URI into the address of your browser will result in the following output:

get-collection

In addition, the template illustrates support in WCF 4 for using the ASP.NET url routing engine, in lieu of an .svc file.  You can see this in action if you take a peek at the code-behind for the global.asax file.

public class Global : HttpApplication {
    void Application_Start(object sender, EventArgs e)
    {
        RegisterRoutes();
    }

    private void RegisterRoutes()
    {
        // Edit the base address replacing the "SampleService" string below RouteTable.Routes.Add(new ServiceRoute("SampleService",
            new WebServiceHostFactory(), typeof(SampleService)));
    }
}

When an HTTP request arrives with a base address of SampleService (which you can change), the WebServiceHostFactory spins up the SampleService and maps the request to an operation, depending on the remaining part of the uri and the HTTP verb used.

// Start the service and browse to <a href="http://:/SampleService/help[ServiceContract]public">http://<machine_name>:<port>/SampleService/help [ServiceContract]
public interface ISampleService {
    [WebGet(UriTemplate = "")]
    List<SampleItem> GetCollection();

    [WebInvoke(UriTemplate = "", Method = "POST")]
    SampleItem Create(SampleItem instance);

    [WebGet(UriTemplate = "?id={id}")]
    SampleItem Get(int id);

    [WebInvoke(UriTemplate = "?id={id}", Method = "PUT")]
    SampleItem Update(int id, SampleItem instance);

    [WebInvoke(UriTemplate = "?id={id}", Method = "DELETE")]
    void Delete(int id);
}

This pattern also illustrates the resource-centric nature of a REST-based services architecture that leverages HTTP verbs for CRUD operations.  This architectural style comes in handy when you want to increase the reach of your service to clients that may not understand or care about SOAP, such as AJAX or Silverlight, or when you want to simplify the contractual footprint of your service by leveraging the uniform interface of the web and taking advantage of the HTTP protocol for things like security and caching.

I hope my WCF REST Template helps you get a better handle on building REST services with WCF. Enjoy.

Posted in Technical | Tagged | 20 Comments

Commands versus Event Triggers in MVVM

Recently I’ve received some questions from the Simple MVVM Toolkit’s discussion forum on when to use commands versus Blend-style event triggers. For several reasons I tend to favor event triggers over commands in most scenarios, especially for Silverlight applications.

Download the code for this blog post here.

  1. One of the main benefits of commands lies in the CanExecute property of ICommand, so that you can enable and disable a control based on a condition.  ICommand exposes a CanExecuteChanged event which when fired causes a binding to check the CanExecute property.  Unfortunately Silverlight requires you to fire the CanExecuteChanged event manually, which is why implementations of ICommand (such as the DelegateCommand in Simple MVVM Toolkit) also expose a public RaiseCanExecute method.
    • You can easily achieve the same result as CanExecute simply by binding the IsEnabled property of a control to a boolean property on the ViewModel.  Then call NotifyPropertyChanged, passing the property name with a lambda expression, whenever you want the binding to check the value of the boolean property.
  2. Currently commands can only be used by controls that derive from ButtonBase, such as a Button or HyperLink Button.  And it can only be used to respond to the button’s Click event.  Other toolkits have an EventToCommand behavior that allows you to invoke a command from events other than Click and with controls other than buttons.  However, you can accomplish much the same thing with a Blend event trigger, without the need for all the extra code required in the ViewModel for a command.
    • You can use an event trigger from the Blend SDK with a CallMethodAction that allows you to invoke a parameterless method on the ViewModel from any event on any control.  The question then arises on how to invoke methods that have input parameters.  You can usually bypass this need because the method in the ViewModel has access to properties on the ViewModel that are bound to controls in the View.  For example, I could have a method called ShowCustomer.  Instead of adding a customer parameter to the method, I can simply reference a SelectedCustomer property on the ViewModel, which can be bound to the SelectedItem property of a combo box in the View.
  3. There is one scenario where I would want to use commands, which is to call a method in the ViewModel that accepts a parameter with a value that cannot be obtained from a property on the ViewModel.
    • A good example of this would be buttons on a calculator.  In this case you would want to pass in arbitrary values to an Add method, which is wired up to an AddCommand.  The CommandParameter property of the button is your friend here.  Simply specify a number corresponding to the relevant button.  The generic DelegateCommand in Simple MVVM Toolkit is implemented in a way that dynamically calls a Parse method on the generic type argument.

Here is what an event trigger would look like, wiring up the SelectionChanged event of a combo box to a ShowCustomer method on the ViewModel. Simple MVVM Toolkit comes with an XML snippet you can use to insert an event trigger / call method action.  To use it you need to open up a view by right-clicking on it in the Solution Explorer and choosing “Open With …” and selecting XML Editor.  Then you should make sure to add a end element for the combo box control (</ComboBox> instead of />).  Right-click in the empty content of the ComboBox element and select Insert Snippet from the context menu. Then open “My XML Snippets” and drill down until you find the “mvvmtrigger” snippet. Type “SelectionChanged” for the event name and “ShowCustomer” for the method name.

<ComboBox Height="23" ItemsSource="{Binding Customers}" SelectedItem="{Binding Path=SelectedCustomer, Mode=TwoWay}"
          HorizontalAlignment="Center" VerticalAlignment="Center" Width="120" Grid.ColumnSpan="2" DisplayMemberPath="CustomerName">
  <!-- Add reference to Microsoft.Expression.Interactions.dll, System.Windows.Interactivity.dll -->
  <!-- Use mvvmxmlns snippet to add i and ei namespace prefixes -->
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
      <ei:CallMethodAction
              TargetObject="{Binding}"
              MethodName="ShowCustomer"/>
    </i:EventTrigger>
  </i:Interaction.Triggers>
</ComboBox>

The ShowCustomer method in the ViewModel looks like this.

public void ShowCustomer()
{
    if (SelectedCustomer != null)
    {
        MessageBox.Show(SelectedCustomer.CustomerName);
    }
}

Let’s take this example a bit further by adding a “Show Customer” button to the View that is only enabled when a customer has been selected.  We start by adding a CanShowCustomer boolean property to the ViewModel, so that we can bind the IsEnabled property of the button to it.

public bool CanShowCustomer
{
    get
    {
        return SelectedCustomer != null && SelectedCustomer.CustomerId > 0;
    }
}

Using the mvvmtrigger XML snippet we can add a trigger for the Click event that executes the ShowCustomer method on the ViewModel.  The button will be disabled when CanShowCustomer returns false.

<Button Content="Show Customer" Grid.Column="1" Height="23" Width="100"
        IsEnabled="{Binding CanShowCustomer}">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="Click">
      <ei:CallMethodAction
              TargetObject="{Binding}"
              MethodName="ShowCustomer"/>
    </i:EventTrigger>
  </i:Interaction.Triggers>
</Button>

The last thing we need to do is fire NotifyPropertyChanged for CanShowCustomer in the setter for the  SelectedCustomer property.

private Customer selectedCustomer;
public Customer SelectedCustomer
{
    get { return selectedCustomer; }
    set
    {
        selectedCustomer = value;
        NotifyPropertyChanged(m => m.SelectedCustomer);

        // Update bindings for CanShowCustomer
        NotifyPropertyChanged(m => m.CanShowCustomer);
    }
}

These examples illustrate how to wire up View events to ViewModel methods without using commands or the need for an EventToCommand behavior.  It works with all events on all controls and can be used to call parameterless methods on the ViewModel. I would only use commands in the case where you want to add a parameter to the ViewModel method with a hard-coded value passed in from the View via a CommandParameter.  For an example of this approach, take a look at my blog post on ViewModel-driven navigation, where I pass in the name of a page to a Navigate method on the ViewModel.

Enjoy,
Tony

Posted in Technical | Tagged , | 9 Comments

Validation with Simple MVVM Toolkit

In version 2.1 of Simple MVVM Toolkit I added support for validation with INotifyDataErrorInfo. This interface obsolesces IDataErrorInfo because it does everything that interface did but enables additional functionality:

  • Multiple validation errors per property
  • Entity-level validation
  • Asynchronous server-side validation

INotifyDataErrorInfo is supported by Silverlight 4, but it is not supported by WPF and will only have limited support in Windows Phone 7.1. The interface is defined as follows:

public interface INotifyDataErrorInfo
{
    bool HasErrors { get; }
    event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
    IEnumerable GetErrors(string propertyName);
}

I believe the best place to implement this interface is at the model-level.  In WCF RIA Services, for example, the Entity class, which is the base class for client-side entities, implements INotifyDataErrorInfo.  Similarly, the ModelBase class in the SimpleMvvmToolkit namespace, implements this interface, for scenarios in which you are not using WCF RIA Services.

In the ViewModelDetailBase class, which accepts a TModel type argument, supports validation with an IsValid property.  It checks to see if the model implements INotifyDataErrorInfo and, if so, returns true if the HasErrors property is true.  When a PropertyChanged event fires on the model, ViewModelDetailBase calls NotifyPropertyChanged for the IsValid property.  You might, for example, bind the IsEnabled property of a Save button to the IsValid property of the ViewModel.  When properties are changed on the Model, the Save button would be disabled if there were any validation errors.

Performing validation with INotifyDataErrorInfo is very powerful.  It integrates well with DataAnnotations, so that you can apply attributes to class properties to enforce validation.  By default, the Binding markup extension supports INotifyDataErrorInfo and will transition to a validation visual state when the ErrorsChanged event fires.  Here is an example of requiring a non-blank value with a maximum string length of 50 characters for the Name property of the Item entity

class Item
{
    [Required()]
    [StringLength(50)]
    public string Name
    {
        get
        {
            return this._name;
        }
        set
        {
            if ((this._name != value))
            {
                this.ValidateProperty("Name", value);
                this._name = value;
                this.RaiseDataMemberChanged("Name");
            }
        }
    }
}

While you could write this code yourself, deriving the Item entity from ModelBase, there’s no need if you are using WCF RIA Services, which automatically inserts the [Required] and [StringLength] attributes based on the database column attributes. The ValidateProperty method calls Validator.TryValidateProperty under the covers, which uses reflection to inspect the data annotation attributes and populate the errors collection for that property. (For more information on entity-level and async validation, see my webinar on WCF RIA Services.)  When there are one or more validation errors, you’ll see a red outline around the offending textbox with a label showing the error message.

item_validation

Notice that the OK button is disabled while there are validation errors.  That is accomplished simply by binding IsEnabled on the button to IsValid on the ViewModel.

<Button Content="OK" Click="OKButton_Click"  
    IsEnabled="{Binding Path=IsValid, Mode=TwoWay}"/>

This example uses a handler in the View code-behind, but more likely you would use either an event trigger (with the Blend SDK installed) or a command with a CanExecute method. (I’ll elaborate on triggers versus commands, and when to use each, in a future post.)

While we’re on the topic of validation, it seems appropriate to discuss another feature added to version 2.1 of the toolkit, which is dirty-checking.  ViewModelDetailBase now sports an IsDirty property.  IsDirty calls an extension method called AreSame, which compares an entity with the clone that is created when BeginEdit is called.  This method simply or’s together the hash codes of each property on the objects and compares them.  Complex objects can override GetHashCode to implement custom comparisons.

One thing I’d like to mention that that, when it comes to validation and dirty-checking, there are certain properties you might want to exclude.  For example, entities in RIA Services have all kinds of properties that you would want to exclude from dirty-checking (EntityState, EntityConflict, EntityActions, etc). ViewModelDetailBase therefore has ModelMetadataProperties property with a list of property names excluded from both validation and dirty-checking.  It is defined as virtual so you can replace it if you wish.

To see validation in action, simply download and install the Simple MVVM Toolkit, then open up the SimpleMvvm-RiaValidation sample application and look at the ItemListViewModel class.

Posted in Technical | Tagged | 10 Comments

Simple MVVM Toolkit 2.1 Released!

There has been some good feedback on the project discussion board for Simple MVVM Toolkit. So I’ve incorporated most of the requested features and improvements and rolled them into an update.

Version 2.1 includes support for validation with INotifyDataErrorInfo for Silverlight apps, and ViewModels now perform dirty-checking. The toolkit has been marked as CLS-compliant so that VB.NET programmers can use it. I’ve made the MessageBus class public so that non-ViewModel classes can use it. And I’ve added navigation support for Windows Phone apps.

There are also new samples demonstrating validation with RIA Services and Windows Phone navigation support.

Download the new version of the toolkit here:
http://simplemvvmtoolkit.codeplex.com/releases/view/69754

It is also available from within the Visual Studio Extensions Manager, which directs you to the gallery:
http://visualstudiogallery.msdn.microsoft.com/74b7d72b-360a-4b5d-a634-01bc970487a4

And on the NuGet open-source gallery:
http://nuget.org/List/Packages/SimpleMvvmToolkit.Silverlight
http://nuget.org/List/Packages/SimpleMvvmToolkit.WPF
http://nuget.org/List/Packages/SimpleMvvmToolkit.WP7

Enjoy!

Tony

Posted in Technical | Tagged | 12 Comments

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 | 21 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 | 26 Comments