Brian Genisio's House of Bilz

  Home  |   Contact  |   Syndication    |   Login
  59 Posts | 0 Stories | 109 Comments | 0 Trackbacks

News

Locations of visitors to this page

Archives

Post Categories

Who am I?

Tuesday, October 20, 2009 #

More Adventures in MVVM Shout it kick it on DotNetKicks.com

I have been taking a few weeks off from my personal studies/experiments in the .Net space to learn more about Ruby and Ruby on Rails (RoR).  I have two main goals for this study:

  1. Get to know another platform as an option for future development
  2. Examine how I can incorporate different concepts into my existing framework

What follows is intended to document my experimentation with the second bullet:  How might we design a ViewModel if we were in Rails?  My thoughts on this are still forming, and I am still a novice in the RoR arena, so cut me some slack :).

I am pretty vocal about my thoughts on the MVVM pattern.  I really like the pattern a lot and I think it solves a lot of problems that I encounter on a daily basis.  Unfortunately, the implementation of the pattern – ViewModels specifically – often get overly complicated.  This is why there are about a dozen major players in this arena.  The plumbing necessary to create a good ViewModel is tedious and error prone.  A good set of abstractions and tools make the job much easier.

The RoR approach to application development uses a lot of conventions to allow the developer to be as expressive as possible without introducing too much plumbing.  The framework facilitates DRY (Don’t Repeat Yourself) so your controllers declare what they do and the magic under the hood plumbs it all together for you.  How can we translate these ideas to a better implementation of the MVVM pattern?  In this article, I will focus on the ViewModel portion of the MVVM pattern.

A classic ViewModel implementation

This view is simple.  There is a text box bound to the Text property in the ViewModel and a button bound to the MakeLowercase command (property) in the ViewModel.  The button is enabled/disabled based on the length of the Text property and clicking on the button will cause the text to go to lowercase.

<TextBox Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Column="0" />
<Button Content="Make Lower" Commands:Click.Command="{Binding MakeLowercase}" Grid.Column="1" />

Next is the ViewModel in its pure (no abstractions) form:

public class MainPageViewModel : INotifyPropertyChanged
{
    public MainPageViewModel()
    {
        MakeLowercase = new DelegateCommand<pobject>(ExecuteMakeLowercase, CanExecuteMakeLowercase);
    }

    private void ExecuteMakeLowercase(object obj)
    {
        Text = Text.ToLower();
    }

    private bool CanExecuteMakeLowercase(object arg)
    {
        return !string.IsNullOrEmpty(Text);
    }

    private string _text;
    public string Text
    {
        get { return _text; }
        set
        {
            _text = value;
            FirePropertyChanged("Text");
            MakeLowercase.RaiseCanExecuteChanged();
        }
    }

    private DelegateCommand<object> _makeLowercase;
    public DelegateCommand<object> MakeLowercase
    {
        get { return _makeLowercase; }
        set
        {
            _makeLowercase = value;
            FirePropertyChanged("MakeLowercase");
        }
    }

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

    public event PropertyChangedEventHandler PropertyChanged;
}

Problems with the traditional ViewModel implementation

  1. Lots of plumbing (Command in the constructor, PropertyChanged in property setters, ExecuteChanged evaluation in the Text setter, etc)
  2. Verbose properties (We can’t use auto-properties because of the need to notify of changes
  3. Unrelated events (Text property needs to know that CanExecuteMakeLowercase needs to be re-evaluated)
  4. INotifyPropertyChanged is error-prone due to string events
  5. Lots of redundancies makes maintenance messy

What a Rails-Inspired ViewModel might look like

public class MainPageViewModel : ActiveViewModel<MainPageViewModel.Properties>
{
    public enum Properties { Text }

    public void Execute_MakeLowercase()
    {
        Set(Properties.Text, Get<string>(Properties.Text).ToLower());
    }

    [DependentUpon(Properties.Text)]
    public bool CanExecute_MakeLowercase()
    {
        return !string.IsNullOrEmpty(Get<string>(Properties.Text));
    }
}

My goal was to reduce the amount of plumbing and redundancies in this code to communicate only what it needs to

  1. There is one property named Text
  2. The MakeLowercase command will act on the Text property and make it lowercase
  3. CanExecuteMakeLowercase will return true if Text has meaningful data
  4. CanExecuteMakeLowercase needs to be re-evaluated with Text changes

There is a lot of magic in ActiveViewModel.  I am using convention to define the properties as a list of enums (Properties).  The ActiveViewModel will generate these properties dynamically.  I am also using convention to create commands.  Any method that is prefixed with Execute_ will be made into a command property.  Any method prefixed with CanExecute_ will be evaluated in the same command.  Further, the CanExecute_ method can declare the properties that will cause the commands to re-evaluate, putting the dependency where it belongs – with the method that is dependant upon it!  Testability is really easy: Call the actions and validate the properties (via public Get()).  I didn’t implement it, but actions based on property setters could very easily use the DependentUpon attribute to avoid INotifyPropertyChanged chaining that can get quite ugly.

Summary

I think this approach has a lot of potential.  I am posting it in order to move the conversation forward.  When the MVVM dust settles, and we have some best practices flushed out, what do we want our ViewModels to look like?  Even though I consider this class experimental and exploratory (not meant to be used in production), I feel compelled to call out some weaknesses that will (or may) need to be addressed for a more production-ready base class:

  1. The ActiveViewModel class will not work in Silverlight.  It relies heavily on custom type descriptors which are not available in Silverlight.  Hopefully, in Silverlight 4.0, we will have some better support for dynamic property generation.  This may be in the form of C# 4.0 (with the DynamicObject.Try[SG]etMember overrides, for instance), property descriptors, or something else (better IronRuby support, perhaps?)
  2. There is not a lot of type safety with the properties.  They are stored internally as plain objects.  The Get method lets you get at a type-casted value, but you need to know it when you ask for it.  We might change the property declaration from an enum to a list of name/type pairs and enforce some better type safety in the base class?
  3. Because there are not properties, we loose “equals semantics”.  Get/Set is harder to read/follow than simply assigning and reading properties

Finally, in case you are curious, you can see my implementation (at the time of this post) of the ActiveViewModel from my Launchpad project.


Friday, September 18, 2009 #

Shout it kick it on DotNetKicks.com

DynamicWrapper project on CodePlex

Edit: DynamicWrapper does not work in SIlverlight as I first though.  My unit tests passed, but in runtime I get an exception when I try to use the class.  I will be looking at some alternatives.

Over the past few weeks, I have been working on a utility that I have wanted for years: something that allows me to apply an interface to an object that matches the contract but doesn’t actually implement the interface.  In other words, I’ve wanted duck typing in C#.  The code and project can be found on CodePlex.  It is set up so you simply copy one file into your solution and use the extension methods.

Why did I want this?  Because I write a lot of unit tests and I develop in .Net with C#.  Because I write way too many wrapper classes to make my code testable.  For example, lets say that I have a class that I want to test and it acts upon a framework object:

public sealed class FrameworkClass
{
    internal FrameworkClass() {}
    
    public int X {get; set;}
    public int Y {get; set;}
    public int Calculate() { return DoSomeStuff(); }
}
public class MyClass
{
    public void DoSomethingWithFrameworkData(FrameworkClass value)
    {
        // Do Something
    }
}

The problem is that I can’t test MyClass because it is dependent upon FrameworkClass which I can never construct myself (it is sealed with an internal constructor and no interface).  The solution for this is simple but tedious – create a wrapper class that implements an interface and proxy through the wrapper class to the real object.  This approach works, but I can say this: I am sick of writing wrapper classes!

This is why I created this DynamicWrapper utility.  It exposes two extension methods: realObject.As<Interface>() and wrapper.AsReal<ConcreteClass>().  It uses Reflection to emit a dynamically generated wrapper class that implements the interface, and wraps your object for you.  It sounds complicated, but it is extremely simple to use.

Here is an example. Start by creating an interface that looks like the FrameworkClass:

public interface ICalculatable
{
    int X {get; set;}
    int Y {get; set;}
    int Calculate();
}

Modify your class to depend on ICalculatable:

public void DoSomethingWIthFrameworkData(ICalculatable value) {}

Now, when you pass the framework class into the MyClass, you can wrap it with the interface:

myObject.DoSomethingWithFrameworkData(frameworkObject.As<ICalculatable>());

If you need the framework object to pass back to the framework, it is really simple:

wrapper.AsReal<FrameworkClass>()

That’s all there is to it!  The utility is very simple.  It just gets me out of the business of writing (and maintaining) wrapper classes. I am now free to get back to real development.

*On a slightly related note, I will be focusing my learning efforts towards Ruby in the coming months.*


Thursday, August 27, 2009 #

More Adventures in MVVM Shout it kick it on DotNetKicks.com

One of the biggest points of friction for me when implementing the MVVM pattern happens when I need to bind commands to events.  When using Prism, I get the Button.Click command binding out of the box, but every other event needs to be wired up individually.  Doing this requires a LOT of boilerplate code that is very easy to get wrong.  In my last post, I published some code to alleviate that pain.  Still, it requires you to write a new behavior and attachment for every event that you want to bind an event to.

For a while now, I have toyed with the idea of just binding commands to events directly.  I ran into a lot of bumps in the road.  For instance, every event handler has a different event argument type.  This requires all of the handlers to be dynamic.  I also couldn’t create an inline command binding – I will surely want to bind more than one event per control – so I need to create a collection of bindings.  Creating arrays of structures created its own troubles – binding only works with FrameworkElements within the visual tree.  This required me to write my own crude binding within my generic behavior.

What follows is very loosely based off of the Chinch MVVM framework.  I tested this code in Silverlight and WPF and it works really well!

Assume I have a ViewModel that looks like this:

public class MainPageViewModel : INotifyPropertyChanged
{
    ...
    public ICommand MouseLeaveCommand { get; private set; }
    public ICommand MouseEnterCommand { get; private set; }
    public ICommand ClickCommand { get; private set; }
    ...
}

I can then bind the commands to events on a control (Button, for instance):

<Button Content="Click Me">
    <Behaviors:Events.Commands>
        <Behaviors:EventCommandCollection>
            <Behaviors:EventCommand CommandName="MouseEnterCommand" EventName="MouseEnter" />
            <Behaviors:EventCommand CommandName="MouseLeaveCommand" EventName="MouseLeave" />
            <Behaviors:EventCommand CommandName="ClickCommand" EventName="Click" />
        </Behaviors:EventCommandCollection>
    </Behaviors:Events.Commands>
</Button>

I no longer need to write any extra code whenever I want to attach commands to my events!  There are a few caveats to this code:

  1. The XAML requires the EventCommandCollection to be declared in the XAML.  I struggled to figure out how to eliminate this but gave up.  Someone smarter than me might be able to tell me what I am doing wrong.
  2. This code does not consider command properties.  Every command assumes a null parameter.  If you need parameters (like data context), then you’ll have to do something differently (either use the old-school mechanism or extend this code to handle some special event types).
  3. You don’t bind directly to the command.  Instead, you declare the name of the command (Notice CommandName is not bound).  The behavior binds for you using a primitive mechanism.

Here is the command behavior that does all the work:

public class Events
{
    private static readonly DependencyProperty EventBehaviorsProperty =
        DependencyProperty.RegisterAttached(
        "EventBehaviors",
        typeof(EventBehaviorCollection),
        typeof(Control),
        null);

    private static readonly DependencyProperty InternalDataContextProperty =
        DependencyProperty.RegisterAttached(
        "InternalDataContext",
        typeof(Object),
        typeof(Control),
        new PropertyMetadata(null, DataContextChanged));

    private static void DataContextChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
        var target = dependencyObject as Control;
        if (target == null) return;

        foreach (var behavior in GetOrCreateBehavior(target))
            behavior.Bind();
    }

    public static readonly DependencyProperty CommandsProperty =
        DependencyProperty.RegisterAttached(
        "Commands",
        typeof(EventCommandCollection),
        typeof(Events),
        new PropertyMetadata(null, CommandsChanged));

    public static EventCommandCollection GetCommands(DependencyObject dependencyObject)
    {
        return dependencyObject.GetValue(CommandsProperty) as EventCommandCollection;
    }

    public static void SetCommands(DependencyObject dependencyObject, EventCommandCollection eventCommands)
    {
        dependencyObject.SetValue(CommandsProperty, eventCommands);
    }

    private static void CommandsChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
        var target = dependencyObject as Control;
        if (target == null) return;

        var behaviors = GetOrCreateBehavior(target);
        foreach (var eventCommand in e.NewValue as EventCommandCollection)
        {
            var behavior = new EventBehavior(target);
            behavior.Bind(eventCommand);
            behaviors.Add(behavior);
        }

    }

    private static EventBehaviorCollection GetOrCreateBehavior(FrameworkElement target)
    {
        var behavior = target.GetValue(EventBehaviorsProperty) as EventBehaviorCollection;
        if (behavior == null)
        {
            behavior = new EventBehaviorCollection();
            target.SetValue(EventBehaviorsProperty, behavior);
            target.SetBinding(InternalDataContextProperty, new Binding());
        }

        return behavior;
    }
}

public class EventCommand
{
    public string CommandName { get; set; }
    public string EventName { get; set; }
}

public class EventCommandCollection : List<EventCommand>
{
}

public class EventBehavior : CommandBehaviorBase<Control>
{
    private EventCommand _bindingInfo;

    public EventBehavior(Control control)
        : base(control)
    {

    }

    public void Bind(EventCommand bindingInfo)
    {
        ValidateBindingInfo(bindingInfo);

        _bindingInfo = bindingInfo;

        Bind();
    }

    private void ValidateBindingInfo(EventCommand bindingInfo)
    {
        if(bindingInfo == null) throw new ArgumentException("bindingInfo");
        if (string.IsNullOrEmpty(bindingInfo.CommandName)) throw new ArgumentException("bindingInfo.CommandName");
        if (string.IsNullOrEmpty(bindingInfo.EventName)) throw new ArgumentException("bindingInfo.EventName");
    }

    public void Bind()
    {
        ValidateBindingInfo(_bindingInfo);
        HookPropertyChanged();
        HookEvent();
        SetCommand();
    }

    public void HookPropertyChanged()
    {
        var dataContext = TargetObject.DataContext as INotifyPropertyChanged;
        if (dataContext == null) return;

        dataContext.PropertyChanged -= DataContextPropertyChanged;
        dataContext.PropertyChanged += DataContextPropertyChanged;
    }

    private void DataContextPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == _bindingInfo.CommandName)
            SetCommand();
    }

    private void SetCommand()
    {
        var dataContext = TargetObject.DataContext;
        if (dataContext == null) return;

        var propertyInfo = dataContext.GetType().GetProperty(_bindingInfo.CommandName);
        if (propertyInfo == null) throw new ArgumentException("commandName");

        Command = propertyInfo.GetValue(dataContext, null) as ICommand;
    }

    private void HookEvent()
    {
        var eventInfo = TargetObject.GetType().GetEvent(
            _bindingInfo.EventName, BindingFlags.Public | BindingFlags.Instance);
        if (eventInfo == null) throw new ArgumentException("eventName");

        eventInfo.RemoveEventHandler(TargetObject, GetEventMethod(eventInfo));
        eventInfo.AddEventHandler(TargetObject, GetEventMethod(eventInfo));
    }

    private Delegate _method;
    private Delegate GetEventMethod(EventInfo eventInfo)
    {
        if (eventInfo == null) throw new ArgumentNullException("eventInfo");
        if (eventInfo.EventHandlerType == null) throw new ArgumentException("EventHandlerType is null");

        if (_method == null)
        {
            _method = Delegate.CreateDelegate(
                eventInfo.EventHandlerType, this,
                GetType().GetMethod("OnEventRaised",
                BindingFlags.NonPublic | BindingFlags.Instance));
        }

        return _method;
    }

    private void OnEventRaised(object sender, EventArgs e)
    {
        ExecuteCommand();
    }
}

public class EventBehaviorCollection : List<EventBehavior>
{ }

Friday, August 21, 2009 #

More Adventures in MVVM  Shout it kick it on DotNetKicks.com

There are several examples on the web that describe the “Attached Behavior” pattern in Silverlight and WPF.  This pattern works really well for binding commands in the ViewModel to controls in the View.  The problem with this is that for every behavior, there is a LOT of boilerplate code that goes along with it.  Because the DepencencyProperties need to be static, they cannot be easily abstracted into a common class. 

If you want to attach a MouseEnterBehavior to a control, you need to create two or three static Dependency Properties in the MouseEnter class.  They are MouseEnter.Command, MouseEnter.MouseEnterBehavior and optionally, MouseEnter.CommandParameter.

    public class MouseEnter 
    {
        private static readonly DependencyProperty BehaviorProperty =
            DependencyProperty.RegisterAttached(
                "MouseEnterBehavior",
                typeof(MouseEnterBehavior),
                typeof(Control),
                null);

        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached(
                "Command",
                typeof(ICommand),
                typeof(MouseEnter),
                new PropertyMetadata(OnSetCommand));

        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.RegisterAttached(
                "CommandParameter",
                typeof(object),
                typeof(MouseEnter),
                new PropertyMetadata(OnSetParameter))

And then the "Change Handlers"

        private static void OnSetCommand(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
        {
            var target = dependencyObject as Control;
            if (target == null)
                return;

            GetOrCreateBehavior(target).Command = args.NewValue as ICommand;
        }

        private static void OnSetParameter(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
        {
            var target = dependencyObject as Control;
            if (target != null)
            {
                GetOrCreateBehavior(target).CommandParameter = args.NewValue;
            }
        }

        protected static MouseEnterBehavior GetOrCreateBehavior(Control control)
        {
            var behavior = control.GetValue(BehaviorProperty) as MouseEnterBehavior;
            if (behavior == null)
            {
                behavior = new MouseEnterBehavior(control);
                control.SetValue(BehaviorProperty, behavior);
            }

            return behavior;
        }

Since the Dependency Properties are static, Silverlight also requires you to in include Get* and Set* static methods:

        public static void SetCommand(Control control, ICommand command) { control.SetValue(CommandProperty, command); }
        public static ICommand GetCommand(Control control) { return control.GetValue(CommandProperty) as ICommand; }
        public static void SetCommandParameter(Control control, object parameter) { control.SetValue(CommandParameterProperty, parameter); }
        public static object GetCommandParameter(Control buttonBase) { return buttonBase.GetValue(CommandParameterProperty); }

This is a classic case of reuse via “Copy and Paste”.  The problem is that there are several places in this code where you need to change three different types and many strings.  If you don’t invoke the magic incantation properly, nothing works.  It will compile but it won’t work (or you will get an obscure XAML parse error).

I cringe whenever I have to employ copy/paste reuse.  In the cases where it is absolutely necessary (such as this), I believe the risk can be reduced proportionately to the complexity of the modification after you paste.  This is why I came up with an Attachment base class to generalize all of this boilerplate code.  The previous code can be reduced to:

    public class MouseEnter : Attachment<Control, MouseEnterBehavior, MouseEnter>
    {
        private static readonly DependencyProperty BehaviorProperty = Behavior();
        public static readonly DependencyProperty CommandProperty = Command(BehaviorProperty);
        public static readonly DependencyProperty CommandParameterProperty = Parameter(BehaviorProperty);

        public static void SetCommand(Control control, ICommand command) { control.SetValue(CommandProperty, command); }
        public static ICommand GetCommand(Control control) { return control.GetValue(CommandProperty) as ICommand; }
        public static void SetCommandParameter(Control control, object parameter) { control.SetValue(CommandParameterProperty, parameter); }
        public static object GetCommandParameter(Control buttonBase) { return buttonBase.GetValue(CommandParameterProperty); }
    }

The only modifications to this copied code exist on the first line. 

What is the class name?  MouseEnter (2 places)
What type of control can the behavior attach to? Control
What type of behavior do you want to attach? MouseEnterBehavior

In addition to the decreased configuration complexity, the actual code that needs to be copied goes from 58 lines of boilerplate code to 11 lines of boilerplate code.  This is a big win, in my opinion.

In this code, I am using the CommandBehaviorBase class from the Prism framework.  It is part of the generic constraints.  If you use something else for your behaviors, replace it as you see fit.  Your own base class for command behaviors would slip in nicely, I am sure.

Here is the Attachment base class:

    public class Attachment<TargetT, BehaviorT, AttachmentT>
        where TargetT : Control
        where BehaviorT : CommandBehaviorBase<TargetT>
    {
        public static DependencyProperty Behavior()
        {
            return DependencyProperty.RegisterAttached(
                typeof(BehaviorT).Name,
                typeof(BehaviorT),
                typeof(TargetT),
                null);
        }

        public static DependencyProperty Command(DependencyProperty behaviorProperty)
        {
            return DependencyProperty.RegisterAttached(
                "Command",
                typeof (ICommand),
                typeof(AttachmentT),
                new PropertyMetadata((target, args) => OnSetCommandCallback(target, args, behaviorProperty)));
        }

        public static DependencyProperty Parameter(DependencyProperty behaviorProperty)
        {
            return DependencyProperty.RegisterAttached(
                "CommandParameter",
                typeof (object),
                typeof (AttachmentT),
                new PropertyMetadata((target, args) => OnSetParameterCallback(target, args, behaviorProperty)));
        }

        protected static void OnSetCommandCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e, DependencyProperty behaviorProperty)
        {
            var target = dependencyObject as TargetT;
            if (target == null)
                return;

            GetOrCreateBehavior(target, behaviorProperty).Command = e.NewValue as ICommand;
        }

        protected static void OnSetParameterCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e, DependencyProperty behaviorProperty)
        {
            var target = dependencyObject as TargetT;
            if (target != null)
            {
                GetOrCreateBehavior(target, behaviorProperty).CommandParameter = e.NewValue;
            }
        }

        protected static BehaviorT GetOrCreateBehavior(Control control, DependencyProperty behaviorProperty)
        {
            var behavior = control.GetValue(behaviorProperty) as BehaviorT;
            if (behavior == null)
            {
                behavior = Activator.CreateInstance(typeof(BehaviorT), control) as BehaviorT;
                control.SetValue(behaviorProperty, behavior);
            }

            return behavior;
        }
    }

And finally, just to complete the example, here is what the MouseEnterBehavior looks like:

    public class MouseEnterBehavior : CommandBehaviorBase<Control>
    {
        public MouseEnterBehavior(Control selectableObject)
            : base(selectableObject)
        {
            selectableObject.MouseEnter += (sender, args) => ExecuteCommand();
        }
    }

And to use it in your XAML, it would look like this:

<Button Behaviors:MouseEnter.Command="{Binding MouseEnter}" Behaviors:MouseEnter.CommandParameter="Optional Paremeter"/> 

Friday, August 07, 2009 #

More Adventures in MVVM

It has been a while since I have posted.  With CodeStock, GiveCamp, Vacation, overtime at work and my other speaking gigs, I have been very busy.  But things are calming down.  I have several posts I’d like to get out, but for the time being, I thought I would post my conversation with David Giard about the MVVM pattern:


Friday, June 19, 2009 #

More Adventures in MVVM Shout it kick it on DotNetKicks.com

imageA demo that I added to my MVVM talk is one that compares a “Ball of Mud” application with a componentized MVVM application with the exact same set of features.  I do this to contrast a messy, un-testable work of code to a cleanly separated, testable work.  The application I chose to write is a Twitter search application in WPF.  When you download the code, you will see two folders: “BallOfMud” and “MVVM”. 

The “Ball of Mud” app includes the entire app in a XAML file and a code-behind.  The code is incredibly dense… it does a TON of stuff, all in one page of code.  Unfortunately, is practically un-testable.  Even if you could test it, the code hits a live twitter.com.  Not the way you want to write tests.  This way of writing software works well for demos, but it certainly does not scale to real-life applications.

The MVVM example, on the other hand, is significantly broken up into components (4 layers).  There are 2 Views (TwitterSearchView and TweetView) with 2 corresponding ViewModels.  Then, there is a Model layer which is responsible for parsing data that comes from the Service layer into “Tweets”.  There is more code than the “Ball of Mud” example, but the code is testable, and modular.  You can swap out different services or models, if you wish.  In fact, in the Model layer, you will find a “CannedData” class that I use when I don’t have an internet connection when I give my presentation.  It just swaps in.  This example might feel like “overkill”, but as the application grows in scope, this architecture will scale exceptionally well.

Twitter Search “Ball of Mud” vs “MVVM”


Friday, June 12, 2009 #

More Adventures in MVVM

Shout it kick it on DotNetKicks.com

Yesterday, I gave my MVVM talk to the public for the first time in Flint, MI.  I will be in Southfield next week and Tennessee the week after that (CodeStock), giving the same talk.  Although I have some changes to make, I thought I would post what I presented last night.  I will probably work on a smaller example that I will also put up here when I am done with it.

The Demo

The demo is a front-end to a recipe database.  It should compile and run out of the box.  It was designed to work against www.eCuisine.com, but it requires you to sign up with them in order to get real data.  To get around that, I have stored some “canned” recipes in the service by default.  If you want to hook it up to use the real eCuisine.com service, simply register with them from www.eCuisine.com and add your email/client ID in the eCuisine.svc.cs file and uncomment the null for the service.  If you don’t do that, everything still works well enough for you to get the feel for the app.

The vast majority of the UI behavior exists in the View-Models and I show a few different approaches to getting View-Models hooked up to the views.

There is also a full suite of tests.  Be sure to check them out for ideas to how you might test your View-Models.

Demo Code

Powerpoint Slides


Friday, May 29, 2009 #

Shout it kick it on DotNetKicks.com

Continuing in my series of “Adventures in MVVM”, I want to talk about a few different approaches to working with List Boxes with the MVVM pattern.  What I am writing here is generally true of all controls that derive from Selector, including ListBox and ComboBox.  This example was developed in Silverlight, but the same concepts also apply to WPF.

The Problem

You have a list box in your view, and you want your ViewModel to do something when an item in the ListBox is selected. You want to do this without any code-behind, using the MVVM pattern.  There are three methods that I have come up with, and I will outline them here.  In this post, I will be using a VERY simple data class in my ListBox called Person with a First and Last name.  It is so simple, in fact, that I have chosen not to include the source for this class.

Method 1: Quick and Dirty SelectedItem binding

This method sets up a SelectedPerson property in the view model and does something when the property is changed. 

public class ViewModel : INotifyPropertyChanged
{
    public ObservableCollection<Person> People { get; private set; }

    private Person _selectedPerson = null;
    public Person SelectedPerson
    {
        get { return _selectedPerson; }
        set
        {
            _selectedPerson = value;
            OnPropertyChanged("SelectedPerson");    
            DoSomething(value);
        }
    }
    // ... rest of ViewModel
}
<ListBox ItemsSource="{Binding People}" SelectedItem="{Binding SelectedPerson, Mode=TwoWay}" />

Pros: This method is quick and simple to get going
Cons: You are introducing side effects in your property code.  If you are OK with this, then read no further.  If this bothers you the way it does for me, then lets look at our next option.

Method 2: Button Command

There are plenty of commanding libraries out there to choose from.  I will take advantage of the Prism commanding system (Microsoft.Practices.Composite.Presentation.Commands).  They have implemented bindable commands for ButtonBase.  The only problem: ListBox is not a ButtonBase.  To get around this, replace the ItemTemplate with a Button that has a template of textblock.

public class ViewModel : INotifyPropertyChanged
{
    public ViewModel()
    {
        PersonSelected = new DelegateCommand<Person>(DoSomething);
        // ... rest of constructor
    }

    public ObservableCollection<Person> People { get; private set; }
    public ICommand PersonSelected { get; private set; }

    // ... rest of ViewModel    
}
<ListBox ItemsSource="{Binding People}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Button Commands:Click.Command="{Binding PersonSelected, Source={StaticResource ViewModel}}" Commands:Click.CommandParameter="{Binding}" >
                <Button.Template>
                    <ControlTemplate>
                        <TextBlock Text="{Binding}" />
                    </ControlTemplate>
                </Button.Template>
            </Button>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Pros: The ViewModel is much more simple with no side effects. 
Cons: The XAML is ugly as sin.  It also changes the behavior of the ListBox in a subtle way.  Every time you select an item, the command fires, not just when it changes.  This is my LEAST favorite approach.  We can do better

Method 3: Bind Commands to the ListBox

The final mechanism is my favorite.  Even though Prism doesn’t give us the ability to bind commands to ListBoxes, we can extend their attached behavior infrastructure such that all ListBoxes and ComboBoxes (or anything that derives from Selector) can take advantage of it.  The ViewModel doesn’t change from “Method 2”, but the XAML does:

<ListBox ItemsSource="{Binding People}" Commands:Selected.Command="{Binding PersonSelected}" />

Pros: Best of both worlds.  Simple ViewModel.  Simple XAML
Cons: You have to write some extensions to the Prism infrastructure.  This code is boilerplate.  I have written some generics that can reduce the boilerplate code somewhat, but not completely, due to the static properties.

The Winner Is….

I like “Method 3” the best.  With a bit of some infrastructure code that you can tuck away, you get to bind the selected items to a command in any case.  It plays well, and it is easy to follow.

But wait… you want the Prism extensions?  Here they are:

public class SelectorSelectedCommandBehavior : CommandBehaviorBase<Selector>
{
    public SelectorSelectedCommandBehavior(Selector selectableObject)
        : base(selectableObject)
    {
        selectableObject.SelectionChanged += OnSelectionChanged;
    }

    void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        CommandParameter = TargetObject.SelectedItem;
        ExecuteCommand();
    }
}
public static class Selected
{
    private static readonly DependencyProperty SelectedCommandBehaviorProperty = DependencyProperty.RegisterAttached(
        "SelectedCommandBehavior",
        typeof(SelectorSelectedCommandBehavior),
        typeof(Selected),
        null);

    public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached(
        "Command",
        typeof(ICommand),
        typeof(Selected),
        new PropertyMetadata(OnSetCommandCallback));

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Only works for selector")]
    public static void SetCommand(Selector selector, ICommand command)
    {
        selector.SetValue(CommandProperty, command);
    }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Only works for selector")]
    public static ICommand GetCommand(Selector selector)
    {
        return selector.GetValue(CommandProperty) as ICommand;
    }

    private static void OnSetCommandCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
        var selector = dependencyObject as Selector;
        if (selector != null)
        {
            GetOrCreateBehavior(selector).Command = e.NewValue as ICommand;
        }
    }

    private static SelectorSelectedCommandBehavior GetOrCreateBehavior(Selector selector)
    {
        var behavior = selector.GetValue(SelectedCommandBehaviorProperty) as SelectorSelectedCommandBehavior;
        if (behavior == null)
        {
            behavior = new SelectorSelectedCommandBehavior(selector);
            selector.SetValue(SelectedCommandBehaviorProperty, behavior);
        }

        return behavior;
    }
}

Wednesday, May 27, 2009 #

Adventures in MVVM Shout it kick it on DotNetKicks.com

I have been spending a lot of time lately thinking about client architecture with Silverlight and to a lesser extent, WPF.  I tend to subscribe to the philosophy that when you make your code testable, you get a lot of other great qualities along with it.  I believe this so strongly that I go out of my way to architect my inherently untestable code in a way that I can, indeed, test it.

Since I have been writing most my code for the Silverlight platform in the past several months, and I wanted very much to write my code test-driven.  I used the Model-View-Presenter pattern (MVP) to implement my view as an interface.  The presenter would hand model objects over to the view and I would bind visual items in my view to the model items.  The presenter would then tell the IView what to do when any real logic came to play.  Over time, however, more and more logic started creeping into the code behind.  I had a lot of data converters to doing my dirty work, blending the code between the model and the view.  The problem is that anything within the IView implementation (aka code-behind) is not easily unit-testable.

organic

As I started to really understand how binding worked in the context of XAML, I found myself wanting to use binding against view-agnostic objects for testability.  Since the view didn’t know anything about the presenter, the only data to bind to was in the model.  Sadly, view-specific data started to creep into model items.  Where ThumbnailData (for instance) was only meta-information that came from my server, it began to gain properties such as Selected and Hidden.  Moreover, what “Selected” means to one part of the UI is different to another part of the UI.

This was not the direction I wanted to go.  In a fit of desperation, a colleague and I sat down and designed a pattern where we had a “ViewState” and a “ViewLogic” class.  “ViewState” was just a set of properties (model data and view properties) that implements INotifyPropertyChanged for the view to bind against and “ViewLogic” manipulated the “ViewState” to add the UI smarts.

The benefits were immediate and obvious.  We started seeing logic that was once in the code-behind move over to the “ViewLogic”.  We immediately received testing benefits.  We could write tests against the “ViewState” as if it were the actual UI.  We even started writing our new features with TDD.  Everything was great!

I was all ready to start blogging about it.  My colleague and I had come up with this fantastic pattern for making testable Silverlight UIs and I wanted to tell the world.  When doing some comparative reading I started seeing the “MVVM” term pop up here and there.  It didn’t take long for me to realize that what we had invented in a bubble was just a subtle variant of the Model-View-ViewModel pattern.  The ViewModel is really just our ViewLogic and ViewState combined into one single class.  It only solidified my belief that this pattern had legs.

Although I sensed some initial skepticism from my team-mates about using the pattern throughout the product, it didn’t take long for them to recognize how important the MVVM pattern would be to our project.  Since adoption our test coverage has skyrocketed with hundreds of useful tests.  The proof is in the pudding.  The vast majority of our bugs that come in have been one of two types of bugs: Missed features or improper binding – two things that the MVVM pattern can’t help prevent.

So, that is how I got so interested in the MVVM pattern.  Because it is relatively new, the community is still working out the best practices.  There is room for experimentation and that can be a lot of fun.  Lets solve the new problems.  Lets push the community in the right direction.  We are already hearing the buzz for Silverlight 3 to contain native support for MVVM (via Prism).  Lets keep this going… and lets have fun doing it!


Friday, May 22, 2009 #

Adventures in MVVM Shout it kick it on DotNetKicks.com

EDIT:

One of the things that I enjoy most about working with MVVM in Silverlight is how new it is.  When I say “new”, I mean that Silverlight doesn’t support the pattern very well out of the box, so the development community needs to step up and solve these problems.  Some solutions are better than others.  In this article, I solved a problem the best way I knew how.  I urge you to read Ward Bell’s comments to this article, and my responses.  After reflecting on it more, I concede that this is not the best way to implement a lightweight bindable command in SIlverlight.

Instead, I should have just read the Prism 2 source code to see how they implemented commands via attached behaviors.  I would have learned that that I learned attached behaviors wrong in the first place.  In Julian Dominguez’s blog post on the topic, he walks you through the thought process for attaching commands via behaviors.  Although this is not the final code that made it into Prism, it is very close.  I recommend reading it.

That being said, I will keep my original text in place.  I think that the thought process for how I got there is very useful for learning… at least I find it useful.  Then, be sure to read the comments, visit Julian’s blog and browse the Prism (CAL) source code.

One of the most important aspects of implementing the MVVM pattern in WPF and SIlverlight is the ability for the UI layer to bind directly to commands in the ViewModel.  The only problem with this:  commands were never implemented in Silverlight.  Even though I (and many others) have ranted about this, our voice has not been heard.  Even with the release of the Silverlight 3 beta, it seems as if we are still pining for commanding in Silverlight.

Many libraries have implemented commands in Silverlight, usually with some sort of static lookup table, mapping buttons to commands.  They include Prism, Caliburn, SilverlightFX and the MVVM toolkit.  It can feel like overkill to bring in these libraries just to get commanding.  There are plenty of good reasons to use these libraries – don’t get me wrong – but if you are just looking for bindable commands, there is an easier way.

This article will walk you through the process of creating a button with command properties.  This technique can be translated easily to any other control in order to achieve bindable commanding in Silverlight.

ICommand

The ICommand interface was the only thing that was included from the WPF commanding infrastructure within Silverlight.  The interface is extremely simple:

interface ICommand
{
    void Execute(object parameter);
    bool CanExecute(object parameter);
    event EventHandler CanExecuteChanged;
}

The requirements of any control that deals with ICommand are:

  1. Call Execute() when a trigger is hit
  2. Only call Execute() if CanExecute() returns true
  3. Allow a bindable parameter to be passed into Execute() and CanExecute()
  4. Disable the control when CanExecute() is false
  5. Refresh the enable/disable state of the control when the CanExecuteChanged event is raised

Implementing CommandButton

Lets start with requirements 1 and 2:

public class CommandButton : Button
{
    public CommandButton()
    {
        Click += (sender, e) =>
        {
            if (Command != null && Command.CanExecute(null))
                Command.Execute(null);
        };
    }

    public static DependencyProperty CommandProperty =
        DependencyProperty.Register("Command",
                                    typeof(ICommand), typeof(CommandButton),
                                    new PropertyMetadata(null));

    public ICommand Command
    {
        get { return GetValue(CommandProperty) as ICommand; }
        set { SetValue(CommandProperty, value); }
    }
}

With this, you can bind a command in the ViewModel to the view:

public class ViewModel : INotifyPropertyChanged
{
    public ViewModel()
    {
        MyCommand = new DelegateCommand<object>(DoSomething);
    }

    private void DoSomething(object obj)
    {
        // Do what you want
    }

    public ICommand MyCommand { get; private set; }

   // The rest of your ViewModel
}

This XAML creates a CommandButton in place of a Button:

<local:CommandButton Content="Click Me" Command="{Binding MyCommand}" />

Adding Parameters

Implementing feature 3 is trivial. Add the CommandParameter property and pass it in to Execute() and CanExecute()

public class CommandButton : Button
{
    public CommandButton()
    {
        Click += (sender, e) =>
        {
            if (Command != null && Command.CanExecute(CommandParameter))
                Command.Execute(CommandParameter);
        };
    }

    // Everything else from initial Implementation
	
    public static DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter",
                                    typeof(object), typeof(CommandButton),
                                    new PropertyMetadata(null));

    public object CommandParameter
    {
        get { return GetValue(CommandParameterProperty); }
        set { SetValue(CommandParameterProperty, value); }
    }
}

With that, you can add parameters to the XAML:

<local:CommandButton Content="Click Me" Command="{Binding MyCommand}" CommandParameter="MyParameter" />

Hooking IsEnabled to CanExecute()

Things get a bit more complicated when implementing requirements 4 and 5, but it is still pretty straight-forward.  I start by registering an event handler for when the Command property changes (CommandChanged).  This event handler hooks the CanExecuteChanged event and handles the event by setting the IsEnabled flag to the value of CanExecute().  It then proceeds to initialize the value of IsEnabled since we know the answer at this time.

The final class:

public class CommandButton : Button
{
    public CommandButton()
    {
        Click += (sender, e) =>
        {
            if (Command != null && Command.CanExecute(CommandParameter))
                Command.Execute(CommandParameter);
        };
    }

    public static DependencyProperty CommandProperty =
        DependencyProperty.Register("Command",
                                    typeof(ICommand), typeof(CommandButton),
                                    new PropertyMetadata(null, CommandChanged));

    private static void CommandChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)
    {
        var button = source as CommandButton;
        if (button == null) return;

        button.RegisterCommand(args.OldValue as ICommand, args.NewValue as ICommand);            
    }

    private void RegisterCommand(ICommand oldCommand, ICommand newCommand)
    {
        if (oldCommand != null)
            oldCommand.CanExecuteChanged -= HandleCanExecuteChanged;

        if (newCommand != null)
            newCommand.CanExecuteChanged += HandleCanExecuteChanged;

        HandleCanExecuteChanged(newCommand, EventArgs.Empty);
    }

    private void HandleCanExecuteChanged(object sender, EventArgs args)
    {
        if (Command != null)
            IsEnabled = Command.CanExecute(CommandParameter);
    }

    public ICommand Command
    {
        get { return GetValue(CommandProperty) as ICommand; }
        set { SetValue(CommandProperty, value); }
    }

    public static DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter",
                                    typeof(object), typeof(CommandButton),
                                    new PropertyMetadata(null));

    public object CommandParameter
    {
        get { return GetValue(CommandParameterProperty); }
        set { SetValue(CommandParameterProperty, value); }
    }
}

Summary

This method for hooking commands to buttons has one drawback in my opinion:  It requires you to put a CommandButton in your XAML instead of a vanilla Button.  This, of course, means that other controls that inherit from Button such as Checkbox and RadioButton do not get this behavior (you have to implement this pattern for them).  Still, this approach makes it very easy to add commands to any control you wish; even in WPF.  In a future post, I will discuss a similar approach for binding a command to a ComboBox (or ListBox) selection changed event.