Archive for the ‘Patterns’ Category

Hands-On MVVM video

Friday, November 5th, 2010

Many thanks to Shawn Weisfeld for recording my Hands-On MVVM session at the Forth Worth .NET User’s Group.

Hands-on MVVM 4b: Communicate through the data model

Friday, May 14th, 2010

I presented this material at Dallas XAML on May 4, 2010. Please download the demo code and follow along. This post takes us the rest of the way the project called “Step4”.

When we left the project in part 4, we had injected a layer between the model and the view. In the process, we broke updates. Now let’s fix them.

Add INotifyPropertyChanged to the view model
Updates stopped working because we are now data binding to the view model. As of yet, the view model does not implement INotifyPropertyChanged. As I mentioned in part 2, there are really only two reasons to ever fire PropertyChanged:

  1. Something other than the view changes the property, or
  2. The property depends upon another property.

Neither WPF nor Silverlight need you to fire PropertyChanged for a property that the view itself is changing. The view already knows that it has changed. It’s the one that changed it!

The updates that failed are all related to dependent properties. DisplayAs depends upon first name, last name, and email. Title depends upon DisplayAs. We moved both of these properties into the view model. So the view model needs to know when these properties change.

Possible solution: interception
Since the view model wraps the data model, it is possible to intercept changes on their way to the data model. The PersonViewModel understands what Title depends upon, and it intercepts all of those properties. It can fire the appropriate PropertyChanged events.

public string FirstName
{
    get { return _person.FirstName; }
    set { _person.FirstName = value; FirePropertyChanged("Title"); }
}

public string LastName
{
    get { return _person.LastName; }
    set { _person.LastName = value; FirePropertyChanged("Title"); }
}

public string Email
{
    get { return _person.Email; }
    set { _person.Email = value; FirePropertyChanged("Title"); }
}

public string Phone
{
    get { return _person.Phone; }
    set { _person.Phone = value; }
}

public DisplayStrategyViewModel DisplayAs
{
    get { return new DisplayStrategyViewModel(_person, _person.DisplayAs); }
    set { _person.DisplayAs = value.DisplayStrategy; FirePropertyChanged("Title"); }
}

When the user changes any of the properties that Title depends upon, the view model fires PropertyChanged for the Title. Title does not depend upon Phone, so that one doesn’t fire. The view model is keeping track of dependencies.

But what about the DisplayStrategyViewModel? It doesn’t intercept the properties that it depends upon. It needs to be notified when FirstName, LastName, or Email is changed. That means that PersonViewModel would have to send these notifications to DisplayStrategyViewModel. That’s too much coupling between the two. Let’s find a different solution.

Better solution: indirect notification

The view models already have something in common. They both know about the Person data model. Let’s allow them to communicate with each other through the data model.

When the PersonDataModel changes one of the properties on the Person object, the DisplayStrategyViewModel should hear about it. It needs to know about those property changes. We have, conveniently enough, a mechanism for listening to property changed events. Although INotifyPropertyChanged is intended for data binding, you can use it for your own internal notification as well.

Person already implements INotifyPropertyChanged. But it used to fire property changed events for dependent properties. Now we want to know about changes to the properties themselves. Let’s add those notifications.

public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public string FirstName
    {
        get { return _firstName; }
        set { _firstName = value; FirePropertyChanged("FirstName"); }
    }

    public string LastName
    {
        get { return _lastName; }
        set { _lastName = value; FirePropertyChanged("LastName"); }
    }

    public string Email
    {
        get { return _email; }
        set { _email = value; FirePropertyChanged("Email"); }
    }

    public string Phone
    {
        get { return _phone; }
        set { _phone = value; FirePropertyChanged("Phone"); }
    }
}

Person no longer keeps track of dependent properties. That’s the view model’s job. Now it’s firing PropertyChanged events so that the view models can collaborate with each other. To close the loop, DisplayStrategyViewModel needs to listen.

public class DisplayStrategyViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public DisplayStrategyViewModel(
        Person person,
        DisplayStrategy displayStrategy)
    {
        _person = person;
        _displayStrategy = displayStrategy;

        _person.PropertyChanged += PersonPropertyChanged;
    }

    private void PersonPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "FirstName" || e.PropertyName == "LastName" || e.PropertyName == "Email")
            FirePropertyChanged("Display");
    }
}

Now when the PersonViewModel changes one of the properties that DisplayStrategyViewModel depends upon, it can notify the view.

Best solution: automatic dependency management

Wouldn’t it be better if you didn’t have to write all of that dependency management code in the view model? You don’t, if you use Update Controls. But this isn’t an Update Controls presentation, so back to doing it manually.

Finish it out

To finish the transition from the interception solution to the notification solution, we remove the interceptors from the PersonViewModel. Instead, that view model also listens to changes.

public class PersonViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private Person _person;

    public PersonViewModel(Person person)
    {
        _person = person;

        _person.PropertyChanged += PersonPropertyChanged;
    }

    void PersonPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        FirePropertyChanged("Title");
    }
}

Now all of the view models listen to changes in the data model. If anything changes the data model, the view model will notify the view of changes to dependent properties. It’s like a publish-subscribe mechanism, but we’re using the data model itself. The data model has become the conduit for messages.

Next time, we’ll upgrade our application to manage a collection of people. In the process, we will dispel some of the myths about ObservableCollection.

Convention-based view model registration

Sunday, May 9th, 2010

When you create a ListBox or ItemsControl, you usually specify an ItemTemplate to render each of the items. You can do so directly in the ItemsControl itself.

<ListBox ItemsSource="{Binding Projects}" SelectedItem="{Binding SelectedProject}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Or you can identify a resource by name.

<UserControl.Resources>
    <DataTemplate x:Key="ProjectItemTemplate">
        <TextBlock Text="{Binding Name}"/>
    </DataTemplate>
</UserControl.Resources>

<ListBox
    ItemsSource="{Binding Projects}"
    SelectedItem="{Binding SelectedProject}"
    ItemTemplate="{StaticResource ProjectItemTemplate}"/>

Either of these methods causes every item to be rendered in the same way. But what if different kinds of items are represented with different views? If you want each item to be rendered according to its type, you can add all of the data templates to the resource dictionary. The list will select the data template based on the item type.

<UserControl.Resources>
    <DataTemplate DataType="{x:Type projects:SoftwareProject}">
        <StackPanel>
            <TextBlock Text="{Binding Name}"/>
            <TextBlock Text="{Binding LinesOfCode}"/>
        </StackPanel>
    </DataTemplate>
    <DataTemplate DataType="{x:Type projects:HardwareProject}">
        <StackPanel>
            <TextBlock Text="{Binding Name}"/>
            <TextBlock Text="{Binding ServerCount}"/>
        </StackPanel>
    </DataTemplate>
</UserControl.Resources>

<ListBox
    ItemsSource="{Binding Projects}"
    SelectedItem="{Binding SelectedProject}"/>

Convention over configuration

You can explicitly add data templates to a resource dictionary if you have only a few closely related types to choose from. But explicit configuration becomes tedious if this set of types changes frequently, if there are many of them, or if they are located in different namespaces. In some cases, it is easier to adopt a convention-based approach.

I started the WPF LOB project on Codeplex to experiment with patterns for line-of-business applications in WPF. One of those patterns is switching among views within the same window. The project defines a base class for view models that represent panes within the window. It uses convention over configuration to associate those view models with their views.

The main form looks for all classes that inherit from Pane and end with the words “ViewModel”. By convention, the view model will be located in a namespace called “ViewModel”. The associated view will be a user control located in a namespace called “View”, and ending with the word “View”. The main form applies that convention to locate the view, and adds a data template to the resource dictionary.

public MainWindow()
{
    InitializeComponent();
    RegisterAllPanes();
}

private void RegisterAllPanes()
{
    // Find all pane view model types in the assembly.
    Assembly assembly = Assembly.GetExecutingAssembly();
    foreach (Type viewModelType in assembly.GetTypes())
    {
        if (typeof(Pane).IsAssignableFrom(viewModelType) && viewModelType.Name.EndsWith("ViewModel"))
        {
            string viewTypeName = viewModelType.FullName.Replace("ViewModel", "View");
            Type viewType = assembly.GetType(viewTypeName);
            if (viewType != null)
                RegisterDataTemplate(viewModelType, viewType);
        }
    }
}

private void RegisterDataTemplate(Type viewModelType, Type viewType)
{
    DataTemplate dataTemplate = new DataTemplate(viewModelType)
    {
        VisualTree = new FrameworkElementFactory(viewType)
    };
    Resources.Add(dataTemplate.DataTemplateKey, dataTemplate);
}

Caliburn

Rob Eisenberg created an MVVM framework called Calliburn that relies heavily on convention over configuration. His framework goes so far as to data bind controls to properties based on convention, rather than configuring each using the “{Binding}” markup extension. Watch his presentation from Mix10. If you would like to develop applications within the realm of his opinion, I recommend investing the time in learning Caliburn. But even if you don’t, you can still use simple techniques like the one above to take advantage of convention over configuration when it makes the most sense.

Hands-on MVVM 4: the View Model layer

Friday, May 7th, 2010

I presented this material at Dallas XAML on May 4, 2010. Please download the demo code and follow along. This post takes us half way the project called “Step4”. The next one will take us the rest of the way, but then the numbers will be out of sync.

In part 3, we added a “Display As” feature to the system. In doing so, the data model started getting messy. This time, we’ll pull those view-specific features out of the data model.

The data model has a job to do. It evaluates domain logic. That’s already enough for a single class. We don’t want to further burden it with managing a view. Robert C. Martin tells us of the Single Responsibility Principle. A class should have only one reason to change. If you’re changing the data model, it’s because you are modifying the domain. You shouldn’t also change it when modifying the behavior of a view. So let’s move that behavior out of the data model. The place it goes is the View Model. We data bind to the view model rather than to the data model.

View-specific properties
The Title property of the Person class exists to serve the view. It’s not the title of a person; it’s the title of a window that displays a person. This is the first to go.

public class PersonViewModel
{
    private Person _person;

    public PersonViewModel(Person person)
    {
        _person = person;
    }

    public string Title
    {
        get
        {
            return "Person - " + _person.DisplayUsingStrategy(_person.DisplayAs);
        }
    }
}

The Person View Model takes a reference to a Person. It uses the Person to provide the desired behavior.

Pass-through properties

The view displays text boxes where the user can edit the properties of a person directly. Since the view is no longer bound directly to the data model, we have to pass these properties through the view model.

public class PersonViewModel
{
    private Person _person;

    public PersonViewModel(Person person)
    {
        _person = person;
    }

    public string FirstName
    {
        get { return _person.FirstName; }
        set { _person.FirstName = value; }
    }

    public string LastName
    {
        get { return _person.LastName; }
        set { _person.LastName = value; }
    }

    public string Email
    {
        get { return _person.Email; }
        set { _person.Email = value; }
    }

    public string Phone
    {
        get { return _person.Phone; }
        set { _person.Phone = value; }
    }

    public string Title
    {
        get
        {
            return "Person - " + _person.DisplayUsingStrategy(_person.DisplayAs);
        }
    }
}

No data is stored in the view model itself. It all passes through to the data model.

One view model per DataContext

The “Display As” combo box has an ItemsSource that is data bound to a collection. Each item in this collection is the DataContext of one combo box item. Before it was a string. Now we’ll make it a view model of its own.

public class DisplayStrategyViewModel
{
    private Person _person;
    private DisplayStrategy _displayStrategy;

    public DisplayStrategyViewModel(Person person, DisplayStrategy displayStrategy)
    {
        _person = person;
        _displayStrategy = displayStrategy;
    }

    public string Display
    {
        get { return _person.DisplayUsingStrategy(_displayStrategy); }
    }
}

Again, this view model passes its behavior through to the Person object. But now it displays that person according to a given display strategy. We use a DataTemplate to show that property in the combo box.

<ComboBox ItemsSource="{Binding DisplayAsOptions}" SelectedItem="{Binding DisplayAs}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Display}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

And now we need to generate these view models.

Project through a factory

The simplest way to generate a collection of view models is to use linq to project a collection of data objects through a view model constructor. In this case, we are listing all of the display options, so we project the values of the DisplayStrategy enumeration. We add this property to the Person View Model.

public IEnumerable<DisplayStrategyViewModel> DisplayAsOptions
{
    get
    {
        return Enum.GetValues(typeof(DisplayStrategy))
            .OfType<DisplayStrategy>()
            .Select(displayStrategy =>
                new DisplayStrategyViewModel(_person, displayStrategy));
    }
}

From the list of DisplayStrategy values, we produce a list of Display Strategy View Models that render the person using different options.

ItemsSource/SelectedItem duality

Finally, the user needs to select one of the display strategies from the combo box. The SelectedItem property provides this behavior. It is the dual of the ItemsSource property: its type must be the same as the IEnumerable generic parameter.

public DisplayStrategyViewModel DisplayAs
{
    get { return new DisplayStrategyViewModel(_person, _person.DisplayAs); }
    set { _person.DisplayAs = value.DisplayStrategy; }
}

This property wraps the DisplayAs selection in a view model so that it agrees with the type of the list.

Equals and GetHashCode

If you were to run the code now, you would see that the window comes up initially blank. But when you select a “Display As” setting, it appears correctly. The problem is that the view cannot find the SelectedItem in the ItemsSource collection. For each property, we created a new Display Strategy View Model. These are two different instances of similar objects. To tell the view that they are indeed the same, we need to implement Equals and GetHashCode in DisplayStrategyViewModel.

public override bool Equals(object obj)
{
    if (obj == this)
        return true;
    DisplayStrategyViewModel that = obj as DisplayStrategyViewModel;
    if (that == null)
        return false;
    return _displayStrategy == that._displayStrategy;
}

public override int GetHashCode()
{
    return _displayStrategy.GetHashCode();
}

Now the view recognizes that they are the same, so the window appears correctly. You must always implement Equals and GetHashCode when you create an ItemsSource/SelectedItem dual.

We have successfully moved the view-specific behavior out of the data model and into a view model. We pass all of the properties that are data-bound to the view through to the data model. By projecting related objects through a constructor, we can keep a view model layer in between the view and the data model at all times.

The application works now, but there are a few places that no longer update. That’s because we didn’t implement INotifyPropertyChanged on the view model to tell the view about dependent properties. In part 4, we’ll add INotifyPropertyChanged to get that behavior back.

Hands-on MVVM 3: ItemsSource and SelectedItem

Wednesday, May 5th, 2010

display_asI presented this material at Dallas XAML last night (May 4, 2010). If you attended, I hope you had as much fun as I did. If not, just download the demo code and follow along.

In part 2, we saw why we need to fire PropertyChanged events. It’s not for the benefit of the properties that the view is changing directly. It’s for the dependent properties.

Display strategy
Now we want to add another new feature to the system. We want to let the user choose how a person is displayed. They can choose from among three display strategies: last-first, first-last, or email.

The chosen display strategy is stored with the person. The user can choose to display one person using their formal name (last-first), and another using their informal name (first-last). It is not a global setting.

The user selects a display strategy from a combo box. We add this to the person view.

<ComboBox Grid.Row="4" Grid.Column="1" x:Name="displayAs"
    ItemsSource="{Binding DisplayAsOptions}" SelectedItem="{Binding DisplayAs}"/>

This combo box needs to show a list of options. We’ll generate these options by applying different display strategies to the person.

public IEnumerable<string> DisplayAsOptions
{
    get
    {
        return Enum.GetValues(typeof(DisplayStrategy))
            .OfType<DisplayStrategy>()
            .Select(displayStrategy => DisplayUsingStrategy(displayStrategy));
    }
}

public string DisplayUsingStrategy(DisplayStrategy displayStrategy)
{
    if (displayStrategy == DisplayStrategy.LastFirst)
        return string.Format("{0}, {1}", _lastName, _firstName);
    else if (displayStrategy == DisplayStrategy.FirstLast)
        return string.Format("{0} {1}", _firstName, _lastName);
    else
        return _email;
}

The DisplayAsOptions property gets all values of the DisplayStrategy enumeration and projects that set through the DisplayUsingStrategy method. The DisplayUsingStrategy method formats the person for the given strategy. The result is a collection of strings.

When the user selects one of those strings, they will set the DisplayAs property. Since DisplayAsOptions is an IEnumerable<string>, DisplayAs has to be a string.

public string DisplayAs
{
    get { return DisplayUsingStrategy(_displayAs); }
    set
    {
        _displayAs = (DisplayStrategy)DisplayAsOptions
            .ToList()
            .FindIndex(option => option == value);
    }
}

The DisplayAs getter just applies the current display strategy for the person. The setter, however, has to find the selected string in the list of options. The index of this string corresponds to the ordinal value of the enumeration that generated it.

The important thing here is the duality of the DisplayAsOptions and DisplayAs properties. DisplayAsOptions has type IEnumerable<string>. DisplayAs has type string. These types must agree, because one is data bound to ItemsSource and the other to SelectedItem.

Update the title

Now that the user can select the display strategy for the person, we should use that display strategy in the title of the window. We make the necessary change to the Title property.

public string Title
{
    get
    {
        return "Person - " + DisplayUsingStrategy(_displayAs);
    }
}

When we run the app, it doesn’t look like it’s working. When we change the display strategy, the title doesn’t update. Did we forget to compile? No. We just forgot to tell XAML that the title depends upon DisplayAs.

public string DisplayAs
{
    get { return DisplayUsingStrategy(_displayAs); }
    set
    {
        _displayAs = (DisplayStrategy)DisplayAsOptions
            .ToList()
            .FindIndex(option => option == value);
        FirePropertyChanged("Title");
    }
}

Now the title updates when we change the display strategy.

Messy model

Take a step back and look at the model that we’ve created. The Person class has the following properties.

  • FirstName
  • LastName
  • Email
  • Phone
  • DisplayAs
  • DisplayAsOptions
  • Title

How many of these are actually the responsibility of the model? How many are just there to satisfy the view? As we’ve added features to the application, we’ve allowed the view’s concerns to creep into the data model. If we continue in this vein, the data model will get very messy.

In part 4, we’ll pull the view’s concerns out of the data model. That’s the first time in this series that we’ll really see the MVVM pattern.

Hands-on MVVM 2: Dependent properties

Tuesday, May 4th, 2010

I will be presenting this material at Dallas XAML tonight (May 4, 2010). If you are in the area, please come by. If not, just download the demo code and follow along.

In part 1 we created a model and a view. Now we start adding features and seeing how our code changes.

Window title
The first feature to add is to display the name of the person in the title bar of the window. The view is a user control, but it’s hosted inside of a window. We already set the DataContext of the window so that it would be inherited by the user control. So we can just data bind the title.

<Window x:Class="Step2.PersonWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:view="clr-namespace:Step2.View"
    Title="{Binding Title}" Height="300" Width="468">
    <view:PersonUserControl/>
</Window>

Bound property

The data context that we set was the Person model object. So we have to add this Title property to the Person.

public class Person
{
    private string _firstName;
    private string _lastName;
    private string _email;
    private string _phone;

    public string FirstName
    {
        get { return _firstName; }
        set { _firstName = value; }
    }

    public string LastName
    {
        get { return _lastName; }
        set { _lastName = value; }
    }

    public string Email
    {
        get { return _email; }
        set { _email = value; }
    }

    public string Phone
    {
        get { return _phone; }
        set { _phone = value; }
    }

    public string Title
    {
        get
        {
            return string.Format("Person - {0}, {1}", _lastName, _firstName);
        }
    }
}

Run the program and you’ll see that the title properly displays the person’s name. It looks like everything is working. But change the name and see what happens.

change_name

The title doesn’t update when the name changes. That’s because the view doesn’t know that the title depends upon the name. Unless you have a system that automatically discovers dependencies (not discussed in this series), you have to notify the view.

As you can see, INotifyPropertyChanged is not strictly necessary for data binding to work. The view worked just fine up until now. The properties were not notifying the view when they themselves were changing. That’s because it was the view that was changing them. The view already knows. You only really need INotifyPropertyChanged to notify the view when:

  1. Something other than the view changes the property, or
  2. The property depends upon another property.

Dependent property

In this case, the Title property depends upon the FirstName and LastName properties. So we notify the view that Title has changed when one of those properties change.

public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string _firstName;
    private string _lastName;
    private string _email;
    private string _phone;

    public string FirstName
    {
        get { return _firstName; }
        set { _firstName = value; FirePropertyChanged("Title"); }
    }

    public string LastName
    {
        get { return _lastName; }
        set { _lastName = value; FirePropertyChanged("Title"); }
    }

    public string Email
    {
        get { return _email; }
        set { _email = value; }
    }

    public string Phone
    {
        get { return _phone; }
        set { _phone = value; }
    }

    public string Title
    {
        get
        {
            return string.Format("Person - {0}, {1}", _lastName, _firstName);
        }
    }

    private void FirePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

And now the title updates when you change the name.

We are starting to see the need for a view model. The Title property has nothing to do with our data model. But we’ll let that slide for now.

Today we saw what problem INotifyPropertyChanged solves, and we wrote the simplest thing that works. This is not the best thing, nor is it the right thing. We are watching the code evolve to see why we need MVVM.

Next time we will add another feature to the system and see how the code responds to another change. Stay tuned.

Hands-on MVVM 1: Model and View

Monday, May 3rd, 2010

I will be presenting this material at Dallas XAML tomorrow (May 4, 2010). If you are in the area, please come by. If not, just download the demo code and follow along.

Microsoft has finally nailed data binding in WPF and Silverlight. It has long been ridiculed as a demo-only feature. But now it is useful in real application development.

As people apply data binding to real applications, patterns have emerged. One of the most prevalent is Model-View-ViewModel. In truth, MVVM is not just one pattern. It is a collection if interrelated patterns. Each person has a different idea of what MVVM actually looks like. This is my opinion.

The goal of this series is to understand why it is good to follow these patterns. We are going to start with direct data binding. We won’t add any code until we need it. When we find that things don’t work, we’ll add code to make them work. When things start to get messy, we will refactor to clean them up.

The model
The application that we are building keeps track of people. It starts innocently enough with a class called Person:

public class Person
{
    private string _firstName;
    private string _lastName;
    private string _email;
    private string _phone;

    public string FirstName
    {
        get { return _firstName; }
        set { _firstName = value; }
    }

    public string LastName
    {
        get { return _lastName; }
        set { _lastName = value; }
    }

    public string Email
    {
        get { return _email; }
        set { _email = value; }
    }

    public string Phone
    {
        get { return _phone; }
        set { _phone = value; }
    }
}

Notice that this class does not implement INotifyPropertyChanged. We are starting simple so we know why we need that code.

The view

We’ll data bind our view directly to our model. Data binding works against properties. The Person user control defines one text box for each Person property.

<UserControl x:Class="Step1.View.PersonUserControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Background="#FF353535">
    <Grid Margin="5">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Label Grid.Row="0" Target="{Binding ElementName=firstName}" Content="_First Name:"/>
        <Label Grid.Row="1" Target="{Binding ElementName=lastName}" Content="_Last Name:"/>
        <Label Grid.Row="2" Target="{Binding ElementName=email}" Content="_Email:"/>
        <Label Grid.Row="3" Target="{Binding ElementName=phone}" Content="_Phone:"/>

        <TextBox Grid.Row="0" Grid.Column="1" x:Name="firstName" Text="{Binding FirstName}"/>
        <TextBox Grid.Row="1" Grid.Column="1" x:Name="lastName" Text="{Binding LastName}"/>
        <TextBox Grid.Row="2" Grid.Column="1" x:Name="email" Text="{Binding Email}"/>
        <TextBox Grid.Row="3" Grid.Column="1" x:Name="phone" Text="{Binding Phone}"/>
    </Grid>
</UserControl>

Notice that the view only contains layout and controls. All of the styling is expressed in App.xaml.

The application

The view needs an instance of the model to bind to. Our application will load this instance from a data source – most likely a database or a web service – and give it to the view. The view is hosted within a window. This is all accomplished in Application_Startup.

DataSource dataSource = new DataSource();
this.MainWindow = new PersonWindow();
this.MainWindow.DataContext = dataSource.GetPerson();
this.MainWindow.Show();

Again, we are keeping it simple. There is no dependency injection. There is no service locator. If we see that we need that code, we will add it.

person_window When you run this program, the Person window appears. It is bound to the person that we loaded from the data source. When you edit the properties of a person, your changes are set directly into the model.

The code is extremely simple, and it worked out-of-the-box. So far we haven’t seen a need to implement INotifyPropertyChanged. Strictly speaking, that interface is not necessary for data binding to work. But very soon we will run into situations in which it is necessary.

Also, we have not yet created a ViewModel. It is not strictly necessary for getting an application working. But again, we will soon see a situation in which it makes our code much cleaner.

In part 2, we will add features to this application. Let’s see how those features look when we bind the view directly to the model.

Table as queue

Wednesday, September 30th, 2009

To play along at home, please download the script for SQL Server 2005. It may work on earlier versions, but I haven't tried it.

Yesterday I said that the data is the queue. It is a mistake to separate the processing of data from the data itself. I proposed an architecture in which there is no workflow orchestration, there are only autonomous worker processes. These processes pick up work based on attributes of the objects on which they act, not based on any external queue.

There are a small number of database patterns that make this possible. One that I often use is Table as Queue.

Setup a test environment
I created a test database called "Queues" to test this pattern. You can find the script attached. As it is now, this script is incorrect. We will correct it as we go along.

The database has two tables. The Order table holds orders that we want to process. If the order hasn't been processed, it has no confirmation number. If it has, it does. The Log table holds a log of all the steps the order processor has gone through. This will help us see how well we are doing.

There are three stored procedures that we'll use. The InsertLoop stored procedure generates some test data. Run this one first. The ProcessLoop stored procedure simulates the ERP process. You'll want to open two query windows and enter "EXEC ProcessLoop" in both of them. Finally, the ViewLog procedure lets us see how we did.

Anatomy of a queue procedure
The ProcessLoop stored procedure begins by selecting one order to process. It returns only the ID of this order.

-- Get a work item
SET @orderId =
  (SELECT TOP 1
	OrderId
	FROM [Order]
	WHERE ConfirmationNumber IS NULL)

This ID has to be the primary key of the table. This is necessary for correct queuing behavior. If it is not the primary key, we will not get the correct locks later.

To process the order, other details about that record will be required. These should be fetched separately by the returned ID. Do not try to combine these steps.

Default isolation level
Right now, the ProcessLoop stored procedure uses the default transaction isolation level (read committed). It starts a transaction, gets an order from the queue, processes it, and updates the confirmation number.

Hit F5 on both of your ProcessLoop query windows. While this is running, run ViewLog. You'll see something like this:

OrderID Action SPID Date/Time
89 Processing 52 2009-09-29 12:51:18.163
89 Processing 53 2009-09-29 12:51:18.337
89 Updating 52 2009-09-29 12:51:19.163
89 Finished 52 2009-09-29 12:51:19.163
89 Updating 53 2009-09-29 12:51:19.337
89 Finished 53 2009-09-29 12:51:19.337
90 Processing 52 2009-09-29 12:51:19.663
90 Processing 53 2009-09-29 12:51:19.837
90 Updating 52 2009-09-29 12:51:20.663
90 Finished 52 2009-09-29 12:51:20.663
90 Updating 53 2009-09-29 12:51:20.837
90 Finished 53 2009-09-29 12:51:20.837

Both of the SPIDs are processing all of the orders. This is clearly not what we want. We want only one SPID to process each order.

Higher isolation level
The other process is able to sneak in between the SELECT and the UPDATE and perform an UPDATE of its own. We want to ensure that the row that the process UPDATEs is the same version it SELECTed. The way to do this is to raise the isolation level to REPEATABLE READ. As the name implies, it ensures that two SELECTs within the same transaction will read the same data. What it also means is that an UPDATE in the same transaction will update the same version of the row. No intermediate UPDATEs will be allowed.

Make the following change to the ProcessLoop procedure:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

Then start the two ProcessLoops again. Before long you will get the error "Transaction (Process ID 53) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction." The other process will still be running.

Kill the remaining process. Close the window so that you can commit the transactions that got left open. Then open a new window and type "EXEC ProcessLoop" again to prepare for the next step.

If you look at the log, you'll see only one of the SPIDs represented. The logs from the other one were rolled back with its transaction.

What happened is that both SPIDs SELECTed the same record. The first one UPDATEd it, which prevented the second from doing so. When it tried to UPDATE, SQL recognized the deadlock and rolled it back.

Update lock
What we want to do is lock the record so that the first one to SELECT it is the one to process it. We'll do this by escalating our read lock to an update lock.

-- Get a work item
SET @orderId =
  (SELECT TOP 1
	OrderId
	FROM [Order] WITH (UPDLOCK)
	WHERE ConfirmationNumber IS NULL)

Now run the two processes and see what happens.

OrderID Action SPID Date/Time
138 Processing 52 2009-09-29 14:05:26.173
138 Updating 52 2009-09-29 14:05:27.173
138 Finished 52 2009-09-29 14:05:27.173
139 Processing 53 2009-09-29 14:05:27.173
139 Updating 53 2009-09-29 14:05:28.173
139 Finished 53 2009-09-29 14:05:28.173
140 Processing 52 2009-09-29 14:05:28.173
140 Updating 52 2009-09-29 14:05:29.173
140 Finished 52 2009-09-29 14:05:29.377

At first glance this looks good. Each order is processed by just one SPID. But look closely at the times. The two processes are taking turns. Each one enters SELECT, but then waits for the other one to commit its transaction before SELECT returns.

Since we've requested an update lock, the higher transaction isolation level makes no difference. We can turn it back down to the default.

Read past
We want each process to skip over locked rows. We do this by specifying the READPAST query hint.

-- Get a work item
SET @orderId =
  (SELECT TOP 1
	OrderId
	FROM [Order] WITH (UPDLOCK, READPAST)
	WHERE ConfirmationNumber IS NULL)

With this hint in place, we get some good behavior.

OrderID Action SPID Date/Time
583 Processing 53 2009-09-29 14:37:21.740
584 Processing 52 2009-09-29 14:37:22.020
583 Updating 53 2009-09-29 14:37:22.740
583 Finished 53 2009-09-29 14:37:22.740
584 Updating 52 2009-09-29 14:37:23.020
584 Finished 52 2009-09-29 14:37:23.020

Now the two processes are running concurrently. Each order is handled by only one process. There are no deadlocks.

With this pattern, the data itself can be used as a queue. But you have to remember the details:

  • SELECT TOP 1 just the primary key of the queue table.
  • Use both the UPDLOCK and READPAST query hints on the SELECT.
  • Fetch additional information by ID in a separate query.
  • After operating on the data, update the record to exclude it from the original WHERE clause.
  • Perform both the SELECT and the UPDATE within the same transaction.

The data is the queue

Tuesday, September 29th, 2009

Our eCommerce system uses BizTalk to process orders. The BizTalk orchestration keeps track of the status of the order. Queues keep track of communications between BizTalk and external systems, like the ERP. The database is updated at all points in the process so the web site reflects the current order status.

This system is fragile.

Problem 1: Diagnostics are scattered
When something goes wrong, there are different ways of observing the system. The customer observes it from the web. They call support to report a problem. Support looks at the system in the Business Activity Monitor (BAM). They call ops. Ops observes the system through Health and Activity Tracking (HAT). If an activity is waiting on the receipt of a message, they will then inspect the appropriate queue. Each of these places holds part of the story.

Problem 2: Things get out of sync
In order to fix a problem, ops needs to take action at some level. They might cancel an orchestration. They might delete a message from a queue. They might manually enter an order into the ERP. When they do, the other parts of the system don't know about the change.

Problem 3: Blocking
One process is querying by status; another is updating it. One process is working on a request; another needs to skip it and go to the next. The workflow problem seems to attract blocking behaviors.

Problem 4: Distributed transactions
When the orchestration moves from one step to another, it needs to update the order status. Before it can wait on the receive queue, it must push to the send queue. It would be disastrous to perform one of these operations without also performing the other. So the BizTalk message box, the order database, and the outgoing and incoming message queues must be accessed within the same transaction. This brings the Distributed Transaction Coordinator into the picture, increasing fragility and exacerbating blocking behaviors.

Here's my solution
There is no need to manage workflow separate from data. This is the fundamental flaw in all workflow systems: BizTalk, WF, MSMQ, Service Broker, just to name a few. They all have their own data storage separate from the subject of the workflow.

If we relied upon the Order table instead of using BizTalk and external queues, we would have a more consistent system. We could diagnose the entire workflow from the database. Having one shared system of record, services would never get out of sync. Certain patterns could be used to eliminate unnecessary blocking. And all transactions would be local.

Broken down in this way, the system no longer has an overarching orchestration. You cannot open a designer and see the workflow. Instead, it has a number of autonomous processes that each move a unit of work further along the pipeline. Each process does its work in the same database.

There is one cardinal rule that makes this possible. The action that a process performs must also remove it from its queue.

A process runs a query to get a work item. It then performs some action on that work item. The outcome of that action is going to be a single database command. That command, whatever it is, must render the work item ineligible for the query.

It is tempting to perform two database commands in the same transaction: record the results of the action and update the work item status. Avoid this pattern. This allows work items to become out of sync. Instead, design one database command that both records the result and disqualifies the work item from the query.

Confirmation number
Let's look at one unit of the order processing orchestration. Take the part of the system that submits the order to the ERP system. This process sends an order to a web service, and receives a confirmation number. So what if we designed this process to use the following query?

SELECT TOP 1 OrderId, OrderDetails FROM [Order] WHERE ConfirmationNumber IS NULL

And then recording the results of the action was:

UPDATE [Order] SET ConfirmationNumber ? WHERE OrderId = ?

This single UPDATE statement disqualifies the order from the SELECT statement. That means that the process will move the unit of work forward, but it can never be out of sync.

Unfortunately, this SELECT ... UPDATE pattern is prone to blocking. We'll look at some patterns that satisfy this cardinal rule without blocking in future posts.

MVVM and Linq to SQL the easy way

Sunday, August 9th, 2009

Download the source code and follow along.

The biggest challenge implementing the MVVM pattern is the View Model responding to changes in the Data Model. Usually, the View Model needs to subscribe to the PropertyChanged events fired by the Data Model, update its internal state, and then fire its own PropertyChanged events for the View. That's the hard way.

The easy way is to use Update Controls. With Update Controls, you just decorate the Data Model and wrap the View Model. The library takes care of everything in between.

Decorate a Linq to SQL data model
You decorate the data model by adding Independent sentries to every property. Whenever the property is accessed, call OnGet(). Whenever it is modified, call OnSet(). To decorate a Linq to SQL data model, we just need to inject these calls into the generated code. Unfortunately, the Linq to SQL code generator does not give you a way to easily tweak its output.

Damien Guard has solved that problem. His open source project LINQ to SQL templates for T4 is incredibly easy to set up and start using. It drops straight into Visual Studio and replaces the build-in code generator with one that you control. With just a few edits to his provided T4 template, I replaced INotifyPropertyChanged with Independent sentries.

I added a sentry for each single-valued property, and called OnGet() inside of the getter and OnSet() in the setter. I also added a sentry for each collection. They require OnGet() in the getter, and OnSet() when something is added or removed. Finally, I added a sentry per table, to take care of the top-level queries. For these, I call OnSet() on any insert, update, and delete. The final T4 template is in the example source code.

Wrap the view model for WPF
Wrapping the view model for the view is a one-liner.

public Window1()
{
    InitializeComponent();

    // Create a data model and a navigation model.
    _blog = new Blog();
    BlogNavigationModel navigationModel = new BlogNavigationModel();

    // Put them both in a view model, then wrap it for the view.
    this.DataContext = ForView.Wrap(new BlogViewModel(_blog, navigationModel));
}

We create a view model based on the decorated data model and a similarly decorated navigation model (more on that later). Then we let Update Controls wrap it up before we give it to the view.

View model per scope
NoteworthyThe example application -- Noteworthy -- is a blog editor. Different parts of the view focus on different granularities of data. The main view (shown in red) focuses on the blog as a whole. The article list items and detail pane (shown in blue) focus on a single article. And the tag list items (shown in green) focus on a single tag.

We define one view model class for each of these three scopes. Each one takes constructor parameters to put itself in context. So the BlogViewModel takes a Blog, the ArticleViewModel takes a Blog and an Article, and the TagViewModel takes a Blog and a Tag.

The DataContext property of a WPF control determines where it begins for data binding. If you don't set it, the control inherits it from its parent. If the control is an item in a list, then it is automatically set to an element of the ItemsSource. Finally, you can data bind to a property of its parent scope. Noteworthy uses all three techniques.

Property per control attribute
WPF data binding connects control attributes to object properties. So within each view model, we define a property for each attribute of a control. The view model exists to serve of the view, so this one-to-one mapping is to be expected. The view model is an isolation layer designed to keep these view-specific concerns out of your data model.

Navigation model per user context
The user of your application has a conceptual model of how controls should work together. Noteworthy is a single window program, so they expect all of the controls on that window to interact appropriately. If it had multiple child windows all within a parent, they would expect each window to be its own context, but participate within the context of the main window. And if it were a composite application, they would expect all of the components to work together.

Where the user draws their conceptual boundary, we create a navigation model. A navigation model records the user's point-of-view as they navigate through the application. It keeps track of their selection and temporary input.

All of the state in the navigation model is transient. Nothing is written to the database. Persistent state belongs in the data model. This keeps the view model completely stateless. The view model has only behavior, which depends upon the data model and the navigation model.

Because the navigation model is transient, we just write fields, select them, and hit Ctrl+D, G to generate the properties. For example, here's the property that records the selected article. The part that I wrote by hand is highlighted:

public class BlogNavigationModel
{
    private Article _selectedArticle;

    #region Independent properties
    // Generated by Update Controls --------------------------------
    private Independent _indSelectedArticle = new Independent();

    /// <summary>
    /// The article for which to display details.
    /// </summary>
    public Article SelectedArticle
    {
        get { _indSelectedArticle.OnGet(); return _selectedArticle; }
        set { _indSelectedArticle.OnSet(); _selectedArticle = value; }
    }
    // End generated code --------------------------------
    #endregion
}

The properties of the navigation model are always data model types, never view model types. The view model depends upon the navigation model, not vice-versa.

Explore on your own
That's just enough to get you started. There are many interesting patterns that came together in the making of Noteworthy. Here are some that you might want to examine on your own:

  • The BlogViewModel.Articles property is filtered by the selected tag.
  • The article detail pane is a Grid within a Grid. The outer grid binds IsEnabled, while the inner grid binds DataContext.
  • The TagListBoxStyle resource binds the ListBoxItem.IsSelected attribute to the TagViewModel.TagIsSelected property to support multiple selection.
  • The Blog data model class uses a Dependent sentry to cache Tags.
  • Every view model setter and command that affects the data model calls SubmitChanges.
  • The ArticleViewModel.AvailableTags property uses .Except() to get all tags not assigned to the article.
  • The BlogViewModel.SelectedArticle property wraps the data object from the navigation model in a view model, and then unwraps it on the way back.
  • The first tag in BlogViewModel.Filters is actually not a tag at all. It is a null to represent the lack of a filter.

Expect future posts to return to this example and explore these points in more detail.