April 2012

Volume 27 Number 04

Leading LightSwitch - The LightSwitch MVVM Model

By Jan Van der Haegen | April 2012

When I first attended a session about Microsoft Visual Studio LightSwitch, I witnessed a working Model-View-ViewModel (MVVM) Silverlight application being created in only a couple of minutes. The application not only looked good, but it was also fully functioning, had validation logic, and as a pièce de résistance, included a “design screen” button in the ribbon that allowed the developer to completely redesign the application while it was running. Figure 1 shows how to edit during run time.

Editing the screen at run time
Figure 1 Editing the screen at run time

Here’s what happens at each numbered step in Figure 1:

  1. A LightSwitch ListDetail screen uses TextBoxes to show a cocktail’s properties.
  2. Click the Design Screen link.
  3. In the RuntimeEditor, with Details Column showing in the Display Name box, select Use Read-only Controls. Press Save.
  4. The View was adjusted at run time and now uses TextBlocks to show the properties. Or was it the ViewModel that was adjusted? (Stay tuned: I answer this question at the end of the article.)

Out of all architectural patterns, MVVM might be one of the most debated.  There are at least a dozen variants on the pattern, and a magnitude more opinions on which one is right. When I witnessed the power of that LightSwitch application, I immediately thought about the LightSwitch team, “They’re the ones who got it right.” Unfortunately, there isn’t enough in-depth documentation online that explains the LightSwitch MVVM implementation in detail. I hope this article will fill in some of the blanks for you. 

Before I explain how the LightSwitch MVVM implements screen redesign at run time, let’s take a couple steps back to make sure that all concepts involved are clear.

Model, View, ViewModel (MVVM)

Because MVVM is an architectural pattern, no single person or organization owns it, which means that it has no official definition.  At the risk of introducing yet another variant, here’s a definition based on my own experience. 

MVVM is an architectural pattern that divides an application into three conceptual layers:

  • The Model layer contains the application’s business logic. In a single-tier application, this layer contains domain objects and repositories; in an n-tier application, it typically includes the proxies to the services, the data contracts and so on.
  • The ViewModel layer is responsible for wrapping the Models in a layer that is easier for the View to interpret, manage and consume.  To accomplish this, ViewModel typically contains classes that represent screens, with simple properties and methods that have simple signatures that encapsulate how the Models interact.  Where needed, the ViewModel layer contains classes that wrap overly complex Models in simplified, flattened classes and take care of common conversions in the process. You can think of ViewModel as the layer that contains any interfaces or classes needed to turn the Models and their interactions into a conceptual application. 
  • The View layer contains the platform-specific implementations that are needed to allow a user to interact with the application (ViewModel).  Typically, this layer consists of XAML files along with required value converters, behaviors and the like.

Here’s a shorthand explanation for understanding MVVM: The Model contains the business logic, the ViewModel turns the business logic into a conceptual application and the View transforms the conceptual application into something users can interact with.

By implementing MVVM as just described, you get the greatest benefits of this architectural pattern:

  • Testability: Both your reusable business logic implementations (Model) and your application (ViewModel) can be fully unit tested.
  • Separation of development and design: Because of the clear separation between ViewModel and View, developers and designers can work side by side on the same application without interfering with each other’s work—or even without knowing anything about each other’s implementation.
  • Increased reusability: Your Models can be reused in different ViewModels, which in turn can be reused in different Views, and even in different applications. For example, Windows Phone, Silverlight and Windows Presentation Foundation applications could share the ViewModel libraries.

To close this section, I offer three tips that will help you get your MVVM implementation right:

  1. Enforce the separation between ViewModel and View by placing the layers in different assemblies. When creating a ViewModel assembly, select a portable class library as the project type (see https://msdn.microsoft.com/en-us/library/hh563947(v=vs.110).aspx).
  2. This separation ensures that your ViewModels can be consumed in Silverlight, Windows Phone and Metro applications, for example, as shown in Figure 2. It also helps you with the composition of your classes. Because the ViewModels are in a portable class library, you can't call an Open File dialog box, for example, which is exactly the kind of code that makes your application hard to unit test.
  3. For each ViewModel, try to create at least four different Views, even if it’s just in your imagination.  If there are properties on the ViewModel that you use in only one of these Views, you probably could replace it with an IValueConverter implementation in that View.   Vice versa, if in each of these views, you need the same IValueConverter implementations, you missed an opportunity to make the life of the designer easier by simply exposing an extra property on your ViewModel.  

Platform-independent MVVM
Figure 2 Platform-independent MVVM

Convention-Based-MVVM

The problem I have with MVVM is that the Views still contain so much unnecessary repetition. To explain this code smell, allow me to describe a small MVVM project and then compare the View with the Model. Figure 3 shows the solution of this project where the portable class library that contains Model and ViewModel is expanded.

MVVM solution with a Silverlight View
Figure 3 MVVM solution with a Silverlight View

Figure 4 shows a Model class for the solution in Figure 3.

Figure 4 CreateNewCocktailCommand Model

public class CreateNewCocktailCommand
{
    publicCreateNewCocktailCommand()
    {
        this.TimeCreated = DateTime.Now;
    }
    public DateTime TimeCreated { get; private set; }
    public string Name {get;set;}
}

To help interact with this Model, I created the ViewModel in Figure 5.

Figure 5 CreateNewCocktailViewModel

class CreateNewCocktailViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public CreateNewCocktailCommand Model { get; private set; }
    private ICocktailRepositorycocktailRepository;
    publicCreateNewCocktailViewModel(ICocktailRepository cocktailRepository)
    {
        this.cocktailRepository = cocktailRepository;
    }
    public void Save()
    {
        this.cocktailRepository.CreateCocktail(this.Model);
        this.refresh();
    }
    public void Cancel()
    {
        this.refresh();
    }
    private void refresh()
    {
        this.Model = new CreateNewCocktailCommand();
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs("Model"));
    }
}

To allow the user to interact with this Model and ViewModel, I can bind a Silverlight View that contains XAML, as shown in Figure 6.

Figure 6 Silverlight XAML taken from the View

<TextBlock Grid.Row="0"Grid.Column="0"
  Text="{Binding Labels.CreateNewCocktailCommand_TimeCreated,
    Source={StaticResourceLocalizedStrings}}" />
<TextBlock Grid.Row="0"Grid.Column="1"
  Text="{Binding Model.TimeCreated}" />
<TextBlock Grid.Row="1"Grid.Column="0"
  Text="{Binding Labels.CreateNewCocktailCommand_Name,
    Source={StaticResourceLocalizedStrings}}" />
<TextBox Grid.Row="1"Grid.Column="1"
  Text="{BindingModel.Name}" />

Consciously or not, we tend to follow certain rules when creating a View for a ViewModel or a Model.   The Model (in Figure 4) has two properties: TimeCreated and Name. For both properties, I followed the same set of rules as when I created the View:

  • Identify the property to the user. For each property, I have to declare a TextBlock that shows a label.  This label has to be localized (translated), so I store the translated text in a resource file and make sure I set a key that is similar to the name of the properties: CreateNewCocktailCommand.TimeCreated and CreateNewCocktailCommand.Name.
  • Pick an input control. For each property that can be edited, I use a TextBox. For read-only properties, I use a TextBlock.
  • Bind that control. For each property, I have to declare a control that binds to the value.  Notice that to create this binding, I again use the name of the property.

I repeat these three rules over and over again, for each property.  And I repeat that for each ViewModel and Model that the user should see or be able to interact with. I could probably repeat these (or similar) rules thousands of times per application.

Thankfully, there’s a way to avoid this repetition.  To start, in Figure 7I introduce an interface in which I describe a property on a metadata level.

Figure 7 Interface describing a property’s metadata

public interface IPropertyViewModel : INotifyPropertyChanged
{
    string Label { get; }
    bool IsReadOnly { get; }
    object Value { get; set; }
}

The beauty of this interface is that it’s extremely small but still provides all the information I need to evaluate my three rules: identify the property to the user, pick an input control and bind that control. 

I can now make a single, more dynamic View user control named PropertyPresenter (shown in Figure 8) to bind to this ViewModel.

Figure 8 PropertyPresenter View

<ControlTemplateTargetType="local:PropertyPresenter">
 <Grid>
  <TextBlock Grid.Column="0"
    Text="{Binding Label}" />
  <TextBlock Grid.Column="1"
    Text="{Binding Value}"
    Visibility="{Binding IsReadOnly,
      Converter={StaticResource BoolToVisibleConverter}}" />
  <TextBox Grid.Column="1"
    Text="{Binding Value}"
    Visibility="{Binding IsReadOnly,
      Converter={StaticResource BoolToCollapsedConverter}}" />
 </Grid>
</ControlTemplate>

By creating this View once and using reflection to fill in the IPropertyViewModel implementation based on the actual properties of the CreateNewViewModel, I can reduce the original XAML to a much smaller version:  

<PropertyPresenterProperty="TimeCreated" />
<PropertyPresenter Property="Name" />

I could probably come up with even smarter implementations that would show, for example, a TextBlock for read-only properties, a NumericUpDown control for write-enabled integer properties, a DatePicker for DateTime properties and a TextBox for all others.

I could even expand my framework to come up with similar conventions and corresponding metadata-ViewModels for methods. I could expand my framework to the point where the only XAML I would have to write is reduced to a single line per View:

<EntityPresenter />

If I work on this convention-based MVVM approach long enough, I could probably remove all XAML repetition from my life and reduce the amount of XAML for a single application to a single line:

<ApplicationPresenter />

Admittedly, this might be a step too far. A couple of steps too far, actually. 

Warning Convention-based MVVM and MVVMVMMD (MV3) are not official or generally accepted terms. They are concepts I use to help explain how LightSwitch implements MVVM.  Using these terms in everyday conversations increases the chance that those around you will perceive you as geeky.

Model, View, ViewModel and ViewModelMetaData (MVVMVMMD, or MV3)

So far, I have explained that the name, type and access modifiers of a property are information referred to as metadata.  For the rest of the article, I’ll split the ViewModel layer in two conceptual parts: traditional ViewModels and this explicit metadata information (now ViewModelMetaData).

Using reflection, I can retrieve this metadata at run time by following predefined conventions.  By binding instances of a dynamic user control to ViewModelMetaData instead of taking the traditional approach of designing different Views for each ViewModel, I can substantially reduce the amount of XAML repetition while still retaining the same visual result (most of the time). Unfortunately, in many cases I still want more fine-grained control over the visual tree than what I can achieve with conventions, no matter how many conventions are defined.

The solution to this problem is not to use reflection at run time but to follow conventions at design time, allowing the designer to change the metadata as he or she wishes.

Examining the Visual Studio LightSwitch IDE shown in Figure 9, you should now be able to understand the concept behind MV3.

LightSwitch IDE
Figure 9 LightSwitch IDE

The Model layer is indicated in red. The Entity Editor is used to create Models in LightSwitch. To learn more about the Entity Editor, see my article “Consume a LightSwitch OData Service from a Windows Phone application” in the March 2012 issue of MSDN Magazine online, at https://msdn.microsoft.com/en-us/magazine/hh875176.aspx, in which I explain the project used in Figure 9 in more detail.

The ViewModel layer is indicated in green. The LightSwitch team refers to this as a ScreenObject Model (see https://blogs.msdn.com/b/lightswitch/archive/2010/08/09/the-anatomy-of-a-lightswitch-application-series-part-2-the-presentation-tier.aspx). Based on this editor, a class will be generated in the client project.

The ViewModelMetaData layer is indicated in blue. LightSwitch generates this layer by following conventions (Name and Business Type of the Model’s properties) defined in a screen template. The metadata will be stored in the ApplicationDefinition.lsml, the hidden heart of any LightSwitch solution, or in more technical terms, in an XML file that stores the ViewModelMetaData and much other metadata information in LightSwitch Markup Language.

If you select any of the elements in Figure 10 and look at its properties, you’ll recognize the rules mentioned earlier in the article:

  1. Identify the property to the user
  2. Pick an input control
  3. Bind that control

Comparing the LightSwitch properties to the IPropertyViewModel
Figure 10 Comparing the LightSwitch properties to the IPropertyViewModel

If you’re wondering where the XAML is, the short answer is that there isn’t any. The long answer is that you’ll have to wait until next month’s Leading LightSwitch article to dive into the View and its extensibility model in more detail. 

I’ll end this article by answering the question I posed earlier: Does the LightSwitch MVVM implementation adjust the View or the ViewModel to let you redesign screens at run time?

As it turns out, that is a bit of a trick question. A LightSwitch application is nothing more than a Silverlight application that allows a user to manage the Models using a variation of classic MVVM.  MV3 has a View layer that binds to a ViewModelMetaData layer, which in turn binds to a ViewModel and a Model layer. So neither the View nor the ViewModel is adjusted to allow you to redesign screens at run time. Instead you’re managing the ViewModelMetaData with a carefully designed LightSwitch control called the RuntimeEditor.

Read the preceding paragraph a couple times. When the aha moment comes, you’ll know that you have successfully wrestled with one of the most undocumented but powerful architectural patterns around: the LightSwitch MVVM model. 

Treat yourself to a beer. You deserve it.


_Jan Van der Haegen* *is a green geek who turns coffee into software. He’s a loving husband, a proud scrum master of an international team at Centric Belgium, and so addicted to learning about any .NET technology—Visual Studio LightSwitch in particular—that he maintains a blog on his coding experiments. _

Thanks to the following technical expert for reviewing this article: Arne Wauters**.**