Tuesday, August 30, 2011

Properties or Fields?

There was a great conversation on Twitter today about properties and fields. The discussion was about whether it makes sense to expose variables as fields and not bother with the overhead of properties. After all, it's quick and easy and you can always change it later, right? One participant suggested there could be design "assumptions / deficiencies / violations / smells" from using properties instead of fields, and someone else pointed out that the intermediate language, or IL, for properties is larger and will take more nanoseconds to process.

So what's the word?

First, I'll make a call to action for you to use the comments section below because I'm curious if anyone has ever had an issue with an application because their properties were too slow. I'm not talking about a property that fires some exotic validation routine that performs asynchronous server operations and crunches numbers approaching infinity before completing. I'm talking a simple property with a backing field and possibly a property change notification. It's highly unlikely the few extra IL codes or nanoseconds spent ever presented any tangible problems just because the implementation was a property and not a field.

So what does the property buy us?

First, it's important to note that just because a property looks like a field to the outside world doesn't mean that it is interchangeable. Changing a field to a property is a breaking change and requires all of your code to be recompiled. That's an expensive operation, and one that should immediately call out to the advantage of using a property from the start. Even though the language allows properties and fields to appear the same, the underlying IL is different. Consider the code to access a field:

ldfld string [MyExample]MyExample.MyClass::SomeVariable
Compared to the code to access the same "field" when it is exposed as a property:
callvirt instance string [MyExample]MyExample.MyClass::get_SomeVariable()

As you can see, the property provides the language convenience of looking like a field but underneath is still a method.

Personally, I believe the best description of the benefits of properties is in Jeffrey Richter's CLR via C#. Chapter 10 covers properties. I obviously don't want to reveal too much because every serious developer should have this book in their library, but I'll summarize a few key points:

  • It's easy to corrupt a field because there is no validation whatsoever (Jeffrey gives the example of assigning a negative age)
  • Properties provide data encapsulation
  • Properties have the benefit of allowing data to be validated and cleansed, and can throw exceptions when something is wrong
  • Properties can perform other actions such as interacting with a cache or triggering a notification
  • Properties can participate in data-binding, fields cannot

Jeffrey's book goes on to make several very insightful comparisons between properties and fields to help you determine the pros and cons for your particular situation. The bottom line is that good design choices are seldom related to reducing the number of keystrokes to complete a class. There are many factors involved and while it is a bit more code to expose a public property, I tend to follow Jeffrey's strong suggestion that all fields should be private, and access to them restricted through methods. Properties have the dual advantage of being special-purpose methods that can perform several tasks when obtaining or presenting a value, while presenting themselves with an interface that looks like a simple field.

Jeremy Likness

Saturday, August 20, 2011

Tablet Development with Microsoft Silverlight

On August 6th I gave a presentation for ReMix South about tablet development with Silverlight. It was a fun presentation to give. I presented using a Motion Computing CL900 to demonstrate the difference between standard applications and ones that are touch-optimized. I also spoke quite a bit about why Silverlight was the strategic choice for a company we had a very successful slate project with (see the Rooms to Go case study here). The project showcased in this talk was written using my Jounce MVVM with MEF framework for building Silverlight line of business applications.

There is a phrase I blogged about earlier called the "consumerization of IT" that is creating some interesting enterprise trends. An IDC survey of 3,000 respondants showed that 95% used devices they personally purchased in their place of work. Workers purchase smart phones and/or tablets and bring them in to use. This is coupled with a strong surge in demand Natural User Interfaces (NUI) as evidenced not only by sales of tablets and slates, but even gaming interfaces like Microsoft's own Kinect technology.

The video for the session is below (hard to see the slides, though). Direct link to the video is here. I've uploaded the slide deck along with the sample applications and source code. Slate and tablet development is a very exciting space for Silverlight and will get even more interesting when we learn the details of Windows 8 in just a few short weeks.

Tablet Development with Silverlight - Jeremy Likness from ReMIX South on Vimeo.

Jeremy Likness

Monday, August 15, 2011

Silverlight 5 Incompatibility: Play by the Rules

I've been using the Silverlight 5 beta for some time now with no issues, so it was a surprise when I came across a project that did not work. It was definitely a backwards compatibility issue because it would run fine in Silverlight 4, but once installed the version 5 runtime, no luck. I started digging deeper and found the culprit. The problem is easy to reproduce. Create a simple command:

public class SelectCommand : ICommand
{
    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        if (parameter != null)
        {
            MessageBox.Show(parameter.ToString());
        }
    }

    public event EventHandler CanExecuteChanged;
}

Then a view model (read-only so it doesn't have to implement property change notification):

public class ViewModel
{
    private ICommand _selectCommand;

    public List<string> Items
    {
        get { return new List<string> {"one", "two", "three", "four"}; }
    }

    public ICommand SelectedCommand
    {
        get { return _selectCommand ?? (_selectCommand = new SelectCommand()); }
    }
}

Now for the Xaml. Here is the rub ... in Silverlight 4, there is no such thing as ancestor binding to easily reference elements higher in the visual tree. It is a common pattern to have a view model with a collection bound to a list, and a command to operate against items in the list. The rub is that the data template for the items is scoped to the item itself, not the parent view model.

There are a number of ways to resolve this, such as using element name binding, but one hack was to stick a content control in the resource dictionary and use it to hold the parent data context. Take a look at this Xaml:

<UserControl.DataContext>
    <DataBindingIssue:ViewModel/>
</UserControl.DataContext>
<Grid x:Name="LayoutRoot" Background="White">
    <Grid.Resources>
        <ContentControl x:Key="BindingContent" Content="{Binding}"/>
    </Grid.Resources>
    <ItemsControl ItemsSource="{Binding Items}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="MouseLeftButtonDown">
                            <i:InvokeCommandAction Command="{Binding Source={StaticResource BindingContent}, Path=Content.SelectedCommand}"
                                                    CommandParameter="{Binding}"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </TextBlock>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

If you compile the example (put the grid in the main page and add the classes described earlier) and run it in Silverlight 4, it works no problem. The content control which is really designed to display UI is being hacked to hold the data context, and then the items can reference back to the control and use the content to bind to the command. When you click on an item in the list, you get a nice message box displaying the value.

This example is not so friendly when run in Silverlight 5. The clicks simply don't happen. You can even convert the project to a Silverlight 5 one, remove and re-add the reference to the System.Windows.Interactivity namespace, and it will still not register clicks. If you debug, you'll find that the trigger does fire. It is passed the command parameter with the value of the item in the list ... but the command is null, so there is nothing for it to call.

Why is that? What happened? If you know the history of Silverlight, since version 3.0 the team has made a monumental effort to keep the versions backwards-compatible. When going to Silverlight 5, you don't get a special Silverlight 4 runtime - you get a 5 runtime that supports all of the Silverlight 4 features. This is obviously a problem for this example because the code breaks.

I filed this as a bug for the Silverlight team to consider in case others have used this technique and need the compatibility, but the "true bug" is in the code itself. This is an example of a hack or an exploitation of a bug that allows something to happen, but isn't necessarily the intended behavior. For all I know the bug was fixed in Silverlight 5. If you dive into the Silverlight documentation for resource dictionaries, you'll find this little nugget:

In order for an object to be defined in and accessed from a ResourceDictionary, the object must be able to be shared ... Any object that is derived from the UIElement type is inherently not shareable, unless it is generated from a control template.

In a nutshell, a content control really doesn't belong in a resource dictionary. Actually, if you think about it, the entire thing is a bit of a hack because a content control is designed to be part of the visual tree and in this example, it's being used simply to marshall a data context.

A better approach would be to create a class that is specifically intended to hold onto the reference. That class is easy enough to create and can even keep the same Content property:

public class DataContextBinder : DependencyObject
{
    public static readonly DependencyProperty ContentProperty =
        DependencyProperty.Register(
            "Content",
            typeof(object),
            typeof(DataContextBinder),
            new PropertyMetadata(null));

    public object Content
    {
        get { return GetValue(ContentProperty); }
        set { SetValue(ContentProperty, value); }
    }
}

That is a simple class that is a dependency object (not a UIElement) and can hold any other type of object. It's not intended for the visual tree and is entirely shareable. And, sure enough, if you replace the content control in the previous example with the data context binder, the code runs fine in both Silverlight 4 and Silverlight 5.

Just another reason to take extra effort to play by the rules and learn what a control expects, so you don't suffer from a "hack" that gets called out in a later version.

Jeremy Likness

Friday, August 12, 2011

Using Attribute Validation in Silverlight with WCF RIA Services Example

I'm not a big fan of attribute-based validation because I find there are often complex requirements that involve asynchronous operations that often break the attribute model. I prefer more fluent validation using rules that can be shared between the client and server and can handle asynchronous scenarios.

For those times when I do have to use a class with attribute validations, it doesn't make sense to ignore them and throw in an entirely new model. Many developers are aware that you can create a "magic" form using the DataForm control, or a "magic" grid with the DataGrid control, and they will automatically honor validation attributes. If you are using your own view models and wiring your own forms, you can still take advantage of data annotations but it requires a little extra work.

In this example I'll use WCF RIA services because it can wire the example up quickly, it automatically projects the data annotations, and because I get a lot of people who ask me for examples using WCF RIA. The example here will work just as well if you use your own POCO classes with annotations in a shared library and send them across the wire with a REST service using JSON.

First, a simple class to encapsulate some data that is decorated with the annotations:

public class Contact
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string FirstName { get; set; }
        
    public string LastName { get; set; }

    [Required]
    [RegularExpression(@"^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$", 
        ErrorMessage = "Email is invalid.")]
    public string Email { get; set; }
}

Next, a simple domain service that exposes what WCF RIA wants to think it is talking to a database layer. Note I am stubbing the CRUD to allow for edits on the client but don't really care about processing them for this example. The one query always returns an example with my information in it.

[EnableClientAccess()]
public class ContactDomainService : DomainService
{
    public Contact GetContact(int contactId)
    {
        return new Contact
                    {
                        Id = contactId,
                        FirstName = "Jeremy",
                        LastName = "Likness",
                        Email = "[email protected]"
                    };
    }

    [Insert]
    public void InsertContact(Contact contact)
    {
            
    }

    [Delete]
    public void DeleteContact(Contact contact)
    {
            
    }

    [Update]
    public void UpdateContact(Contact contact)
    {
            
    }
}

This is where the beauty of WCF RIA services comes into play, and I won't deny it: build the application, and you're ready to go with grabbing and manipulating the data on the client. Before you build the view model you can create a helper class that uses the data annotations validation to process the attributes on the entity. While I wouldn't normally overload the same class to also take on the work of a command, the helper will also implement ICommand to demonstrate how it can be used to also control whether or not the user is able to save the form based on validations (this keeps the example simple - normally I would have a second command class that interacts with the validation helper).

The bulk of the class is straightforward. It is typed to a class that implements property change notification, and registers for this (it also exposes a method to release the registration to avoid issues with memory leaks). Whenever a property changes, it uses reflection to grab the value and then passes all of the information over to the data annotations validation class. That class will throw an exception if the validation fails, and the helper traps this and uses it to keep track of properties that have validation errors before re-throwing it for the Silverlight validation system to use. I'm keeping it simple here and using strings but you can tweak it based on this post.

public class ValidationHelper<T> : ICommand where T : class, INotifyPropertyChanged
{
    private readonly T _instance;

    private readonly Dictionary<string,bool>  _hasErrors 
        = new Dictionary<string, bool>();

    public ValidationHelper(T instance)
    {
        _instance = instance;
        _instance.PropertyChanged += _InstancePropertyChanged;
    }

    public void Release()
    {
        if (_instance != null)
        {
            _instance.PropertyChanged -= _InstancePropertyChanged;
        }
    }

    private void _InstancePropertyChanged(object sender, PropertyChangedEventArgs e)
    {

        _hasErrors[e.PropertyName] = false;            

        var value =
            typeof (T)
                .GetProperty(e.PropertyName)
                .GetGetMethod()
                .Invoke(_instance, null);
            
        try
        {
            Validator.ValidateProperty(
                value,
                new ValidationContext(_instance, null, null)
                    {
                        MemberName = e.PropertyName
                    });
        }
        catch
        {
            _hasErrors[e.PropertyName] = true;
            throw;
        }
        finally
        {
            RaiseCanExecuteChange();
        }
    }
}

The implementation of the command interface takes one more step. Because a user might change some text and then click submit before validation fires, the command implementation will validate the entire object before determining whether or not it is safe to submit. The command is conditioned by the existence of any errors in the error dictionary. Note that the execute methods uses a different approach that doesn't throw exceptions and simply flags the individual errors generated by the call.

public bool CanExecute(object parameter)
{
    return _hasErrors.Keys.All(key => !_hasErrors[key]);
}

public void Execute(object parameter)
{
    var errors = new List<ValidationResult>();

    if (Validator.TryValidateObject(
        _instance,
        new ValidationContext(_instance, null, null),
        errors))
    {
        MessageBox.Show("Success!");
    }
    else
    {
        foreach (var member in errors.SelectMany(error => error.MemberNames))
        {
            _hasErrors[member] = true;
        }
        RaiseCanExecuteChange();
    }
}

The view model keeps an instance of the validation helper and tracks changes to the current contact, spinning up a new helper as needed. It also exposes an edit flag to disable editing while it is loading the data.

public class MainViewModel : INotifyPropertyChanged
{
    private ValidationHelper<Contact> _helper;
    private Contact _contact;

    private readonly string[] _properties = 
        new[] {"FirstName", "LastName", "Email"};

    protected Contact CurrentContact
    {
        get { return _contact; }
        set
        {
            if (_helper != null)
            {
                _helper.Release();
                _helper = null;
            }

            _contact = value;

            if (_contact != null)
            {
                CanEdit = true;
                _helper = new ValidationHelper<Contact>(value);
                RaisePropertyChange("SaveCommand");
            }

            RaisePropertyChange("Contact");
            foreach(var property in _properties)
            {
                RaisePropertyChange(property);
            }
        }
    }

    private bool _canEdit;
    public bool CanEdit
    {
        get { return _canEdit; }
        set
        {
            _canEdit = value;
            RaisePropertyChange("CanEdit");
        }
    }
}

It exposes the validation helper as a command and also projects all of the properties on the underlying contact object:

public ICommand SaveCommand
{
    get { return _helper; }
}        

public string FirstName
{
    get { return CurrentContact == null ? string.Empty : CurrentContact.FirstName; }
    set { CurrentContact.FirstName = value; }
}

public string LastName
{
    get { return CurrentContact == null ? string.Empty : CurrentContact.LastName; }
    set { CurrentContact.LastName = value; }
}

public string Email
{
    get { return CurrentContact == null ? string.Empty : CurrentContact.Email; }
    set { CurrentContact.Email = value; }
}

In the constructor, it either creates a design-time instance or uses WCF RIA services to load an instance of the contact record:

public MainViewModel()
{
    if (DesignerProperties.IsInDesignTool)
    {
        CurrentContact = new Contact
                        {
                            Id = 1,
                            Email = "[email protected]",
                            FirstName = "Jeremy",
                            LastName = "Likness"
                        };
        return;
    }

    var ctx = new ContactDomainContext();

    var query = ctx.GetContactQuery(1);
    ctx.Load(
        query,
        contact =>
            {
                CurrentContact = contact.Entities.Single();
            },
        null);
}

The Xaml to wire this up is straightforward - here is an example combination of a label and a text box:

<TextBlock Text="Last Name:" Grid.Row="1"/>
<TextBox Text="{Binding Path=LastName, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}" 
            IsEnabled="{Binding Path=CanEdit}"
            Grid.Row="1"
            Grid.Column="1"/>

That's it - run the application and edit the fields. You'll see all of the attribute validations come across nicely. If you delete the first name, then click the submit button without tabbing out of the field, the validations will still fire and the submit button will disable itself until you fix the error. As you can see, it's very straightforward to tap into existing attribute-based validations. If you are implementing one of the newer interfaces like INotifyDataErrorInfo, you can use the "try" methods on the validator to avoid throwing exceptions, and parse the results to set errros on the underlying interface instead.

You can download the source for this example here (don't forget to set the web project as the startup project and the aspx page as the start page).

Jeremy Likness