Home » Posts tagged 'Frameworks'

Tag Archives: Frameworks

Growing an MVVM Framework in 2003, part V – Reflections and Regrets

This post is from a series on my experiences starting to grow an MVVM Framework in .NET 1.1.

Full source code can be found in my Google Code repository.

I haven’t added any articles to this series in a while. The main reason is that I’ve not done any more work on the framework. I was able to complete my application using the tools using the Framework So Far, and I’ve long since moved on to other projects. I wanted, though, to take a quick look back and evaluate the project.

I did it!

Way back in part 1, I said that I wanted to create an application that

  • had testable logic, even in the GUI layer,
  • had no “codebehind” in the view, and
  • shunted the tedious wiring up of events and handlers into helpers (or a “framework”)

I’m very pleased with how all this turned out. Taking things in reverse order:

  • The little framework does an excellent job of handling the tedious event-wiring. Handling an View event requires nothing more than declaring a method with a convention-following name and the correct signature, such as
    public void FindClick(object sender, EventArgs e)

    Properties are wired up in a similar way, by declaring a public field with a convention-following name and an appropriate type (StringProperty, BoolProperty, or ListProperty).

  • Aside from setting some properties on View elements (for example, the Find button is initial disabled), there was no need to crack open the View’s .cs file – I never saw the inside of it.
  • The easily-invoked event handlers and the property bindings made writing unit test as easy as writing tests for a non-GUI component: set some initial properties, poke the ViewModel by invoking an event handler, and check the properties. Done! Injecting mock model components was the hardest thing, and that’s no different than in any other test.

If only I had

There was one nagging problem that I left unresolved. My Model contains only synchronous operations, so the View doesn’t update while we’re accessing the data store. As it turns out, the operations are very quick, so the user is unlikely to notice.

I could have implemented asynchronous operations on the view, or used delgates or background threads to explicitly invoke the model in the background. I really would’ve liked to implement something that would be applicable to a larger problem set. Something like Caliburn.Micro’s IResult and Coroutines:
Returning an IResult or a collection of them to be executed on background threads by the framework, while the GUI updates and the ViewModel is none the wiser.

Ah well, time was running out, and there didn’t seem to be that much benefit. Maybe next time…

I would have liked to

There are a few other “features” that I would’ve liked to add to the framework, but there wasn’t time, nor did there seem to be an immediate need:

  • a View binder — After writing a class to bind the ViewModel to the fake storage properties, I realized that that was a nicer approach than having the binding code in the ViewModelBase. I’d like create a “production binder” to hook up the ViewModel and View.
  • composable ViewModels — BookFinder is very simple, with only a TextBox and a few ListBoxes and Buttons on its View, so a single View and ViewModel was sufficient. It would be useful to be able to build up a more complicated GUI by walking a tree of ViewModels and composing a GUI out of corresponding View components.
  • deregistering event handlers — The framework registers event handlers between the ViewModel and View, with no provision for unregistering them when components are no longer neeed. In BookFinder, the single View/ViewModel pair hang around until the application is closed, but in a more complicated application there might be an opportunity to leak resources.

Summing up

I’m happy with how the framework and tool turned out. I could probably have written the application more quickly if I hadn’t bothered trying to extract the framework, but it wouldn’t have been as testable (and therefore likely not as well tested). I think the extra effort was worthwhile both because it created a better application and because I learned more about WinForms programming and how I can leverage conventions to reduce programmer workload – if the framework were used for a second application, development would just fly. And the exercise was fun. Not only writing the framework, but using it — it’s extremely liberating having event handlers just work by creating a properly-named method, and having the handler be immediately testable is a joy. If I had any expectations that I’d be writing similar tools on .NET 1.1 again, I’d definitely continue extending the framework.

Growing an MVVM Framework in 2003, part IV – Unit Tests

This post is from a series on my experiences starting to grow an MVVM Framework in .NET 1.1.

Full source code can be found in my Google Code repository.

In parts 1 and 3 (and 2, but I like part 3 better) I showed a tiny “framework” for binding View properties and events to properties and methods on a ViewModel. In addition to avoiding the tedium and noise of wiring up events by hand, I’d hoped to implement a structure that would make unit testing easier. Let’s see how that went.

Event handlers just work. Almost

Recall that event handlers are defined on the ViewModel as plain old methods that happen to take a specific set of arguments – usually object and something that derives from EventArgs. This means that nothing special has to be done in order to exercise the methods during a unit test. The test doesn’t have to trick the ViewModel into registering with an event or anything. The test just calls the method. And if the method doesn’t care much about its arguments like FindClick doesn’t, you can pass in nonsense:

public class BookListViewModel
{
    public void FindClick(object sender, EventArgs e)
    {
        ICollection books = bookDepository.Find(TitleText.Value);
        IList bookListItems = BookListItems.Value;

        bookListItems.Clear();
        foreach ( string book in books )
        {
             bookListItems.Add(book);
        }
    }
}

public class BookListViewModelTests
{
    [Test]
    public void CallFindClick()
    {
        vm.FindClick(null, null);
    }
}

Of course, this isn’t much of a test. Usually we’ll want to set up some initial state for the ViewModel, and verify that the correct actions have been taken. In fact, as things stand, the property fields will all be null, so TitleText.Value and BookListItems.Value will error out.

Putting something behind the properties

Most event handlers will need to access the properties on the ViewModel, so the tests must hook up the properties.

Provide stub properties

Last time I mentioned that the PropertyStorageStrategy would bring value. This is it. Recall the definitions of the ListProperty and the PropertyStorageStrategy:

public class ListProperty: Property
{
    public ListProperty(PropertyStorageStrategy storage): base(storage)
    {}

    public IList Value
    {
        get { return (IList) storage.Get(); }
        set { storage.Set(value); }
    }
}

 public interface PropertyStorageStrategy
 {
     object Get();
     void Set(object value);
 }

The ListProperty (and BoolProperty and StringProperty) merely consult a PropertyStorageStrategy to obtain a value and they cast it to the correct type. Providing a dumb strategy that, instead of proxying a property on a View control, just holds a field will produce a property that can be used in tests:

public class ValuePropertyStrategy: PropertyStorageStrategy 
{
      private object obj;

      public ValuePropertyStrategy(object initialValue)
      {
         this.obj = initialValue;
      }

      public void Set(object value) { obj = value; }
      public object Get() { return obj; }
}

Then the test fixture setup can bind properties to the ViewModel:

[SetUp]
public void SetUp()
{
    vm = new BookListViewModel(new Control(), new FakeBookDepository());
    vm.TitleText = new StringProperty(new ValuePropertyStrategy(""));
    vm.BookListItems = new ListProperty(new ValuePropertyStrategy(new ArrayList()));
    ...
}

And tests can be constructed to provide initial property values (if the default isn’t good enough) and interrogate them afterward.

[Test]
public void FindClick_WithTitleG_FindsEndersGame()
{
    vm.TitleText.Value = "G";
    vm.FindClick(null, null);

    Assert.IsTrue(vm.BookListItems.Value.Contains("Ender's Game"));
}

Auto-wiring the properties

This works, and pretty well. There’s not that much noise associated with setting up the fake properties. Still, why should there be any? After so much trouble to remove the tedious wiring up from the production code, it seems wrong to leave it in the testing code.
Also, I’m against anything that adds a barrier to writing tests. And having to hand-wire a few (or a dozen) properties before you can start testing is definitely a barrier.

So, let’s write a little code to handle the tedium for us.

public class ValuePropertyBinder
{
      public static void Bind(ViewModelBase viewModel)
      {
          foreach ( FieldInfo field in viewModel.PropertyFields() )
          {
              ValuePropertyStrategy propertyStorageStrategy = new ValuePropertyStrategy(MakeStartingValue(field.FieldType));

              ConstructorInfo propertyConstructor = field.FieldType.GetConstructor(new Type[] {typeof (PropertyStorageStrategy)});
              object propertyField = propertyConstructor.Invoke(new object[] {propertyStorageStrategy});
              field.SetValue(viewModel, propertyField);
          }
      }

      private static object MakeStartingValue(Type fieldType)
      {
         Type propertyType = fieldType.GetProperty("Value").PropertyType;
         
         if ( propertyType == typeof(IList) ) { return new ArrayList(); }
         if ( propertyType == typeof(string) ) { return ""; }
         if ( propertyType == typeof(bool) ) { return false; }
         else
         { 
              throw new NotImplementedException("no known starting value for type " + propertyType);
         }
      }
}

This is very similar to the wiring we’ve seen before – find property fields, construct an object to implement the property, and hook it up. The only thing likely to need attention in the future is MakeStartingValue. A new property type(like DateTime), will require an expansion to the if chain. But that should be very infrequent.

Now it’s much easier to use the ViewModel in tests:

[SetUp]
public void SetUp()
{
   vm = new BookListViewModel(new Control(), new FakeBookDepository());
   ValuePropertyBinder.Bind(vm);
}

An alternative: brute force and ignorance

This approach didn’t occur to me until the project was over. Sigh.
The production code works by binding the ViewModel to a View. The test setup could do that. I’d taken pains to keep any kind of code or behaviour out of the View, so there shouldn’t be any side effects, and there’s no need to show any of the GUI elements. Honestly, the technical downsides seem pretty limited.

Even so, I don’t like this solution. For the BookFinder application, the View is simple enough that I’m confident the approach would work, but I have concerns over using it in a more complex application. Also, I prefer to reduce the amount of auxiliary production code that’s used in tests. In the off chance that something does go wrong, it’s nice to be able to have a small set of production code to look at

Summing up

With the ValuePropertyBinder (or much-maligned “just bind the ViewModel to the actual Model”), tests are really easy to set up and run. As easy as writing the production code. And they’re readable. The only troublesome dependencies are the models. Totally worth the effort.

Growing an MVVM Framework in 2003, part III – Properties Redux

This post is from a series on my experiences starting to grow an MVVM Framework in .NET 1.1.

Full source code can be found in my Google Code repository.

A Change of Plans

Last time I showed how I managed the binding of ViewModel properties to the properties on the View’s controls. I promised to talk this time about how the use of the mini-framework affected the testability of the code. I changed my mind – I want to return to the whole properties discussion.

Festering Dissatisfaction

The method I had for binding ViewModel properties to the View worked, but it left a bad taste in my mouth. A few things bothered me about the implementation. Recall that to add a bound property the ViewModel had to have code something like this:

private Property bookListItems;
public string BookListItems
{
    get { return bookListItems.AsList(); }
    set { bookListItems.Value = value; }
}

I have a couple of problems with this.

  1. it’s pretty chatty
  2. the client programmer has to know when to use .AsList() or not, since strings and bools don’t require it
  3. the viewbinding code had to look for the private field, and that just felt gross

Poor man’s generics

When I first wrote the code, I was bothered a little by the weaknesses in the property bindings. It wasn’t until I wrote about the code here that the suck really started to get to me. And worse, I was unhappy with what I’d wrote. One phrase from the post kept coming back to me:

At this point, I was really missing generics.

What did I mean by that? Why did I miss generics? I hadn’t explained that well, even to myself. So I thought about it. What would I do with the generics if I had them? And I thought for a bit longer. Then I had it. I’d make a Property class to proxy the view’s properties – that would tighten up the code and relieve programmers of the burden of knowing when to us .AsList..

Well, I don’t have generics, but I do have Manual Type Creation. That’s somewhat less convenient, but it’s not like I’m going to need dozens of different property types – 3 will do for a start. So I decided to see what I could do with a little Property type hierarchy.

public abstract class Property
{
    protected PropertyStorageStrategy storage;

    protected Property(PropertyStorageStrategy storage)
    {
        this.storage = storage;
    }
}

public class ListProperty: Property
{
    public ListProperty(PropertyStorageStrategy storage): base(storage)
    {}

    public IList Value
    {
        get { return (IList) storage.Get(); }
        set { storage.Set(value); }
    }
}

public class StringProperty: Property
{
    // pretty much what you'd expect
}

public class BoolProperty: Property
{
    // pretty much what you expected above, only more Bool-y
}

There’s not a terrible amount here, just a family of properties. Each concrete class is responsible for providing a Value property that will return (or accept) a typed value. The real work is done by the storage member – it keeps track of the untyped value that the concrete class will take or dole out. As the name PropertyStorageStrategy suggests, a Property can vary the source and sink for its value via the Strategy design pattern.

I was holding it for a friend

Let’s look at the storage strategy that defers to a property on another object.

 public interface PropertyStorageStrategy
 {
     object Get();
     void Set(object value);
 }

public class BoundPropertyStrategy: PropertyStorageStrategy 
{
      private object obj;
      private PropertyInfo propertyInfo;

      public BoundPropertyStrategy(object obj, PropertyInfo property)
      {
         this.obj = obj;
         this.propertyInfo = property;
      }

      public void Set(object value)
      {
         propertyInfo.SetValue(obj, value, null);
      }

      public object Get()
      {
         return propertyInfo.GetValue(obj, null); 
      }
}

Unsurprisingly, this looks a lot like the BoundProperty class from last time. After all, the core functionality is pretty much the same. So, inject a BoundProperty into one of ListProperty, StringProperty, or BoolProperty, and we get a strongly-typed proxy for the underlying object.

Tying it together

Of course the new classes required a change to the ViewModel/Model binding code. Locating the ViewModel fields to bind is pretty much the same as it was, except only public fields that derive from Property are considered. The BindFieldToControl becomes the slightly-better named BindPropertyToControl:

private bool BindPropertyToControl(Control control, FieldInfo field)
{
    string controlPropertyName = ControlAttributeName(control, field.Name);
    if ( controlPropertyName == null )
    {
        return false;
    }

    PropertyInfo controlProperty = control.GetType().GetProperty(controlPropertyName, myBindingFlags);
    if ( controlProperty == null )
    {
        return false;
    }
     
    BoundPropertyStrategy strategy = new BoundPropertyStrategy(control, controlProperty);
    ConstructorInfo constructor = field.FieldType.GetConstructor(new Type[] {typeof (PropertyStorageStrategy)});
    object propertyField = constructor.Invoke(new object[] {strategy});
    field.SetValue(this, propertyField);
    return true;
}

The first part of the method just makes sure that the control we’ve found has a name that matches the first part of the property. Then we look for a property on the control that completes the name. Once those hurdles are past, the magic happens:

  1. create a new BoundProperty to proxy the control’s property value
  2. take the property field type and find the constructor that takes a PropertyStorageStrategy
  3. make a new property object, passing in our BoundProperty
  4. set the property object onto the ViewModel

How’s it work?

Overall, I think okay. Here’s a sample of the ViewModel code.

public StringProperty TitleText;
public BoolProperty FindEnabled;
public ListProperty BookListItems;

public void TitleTextChanged(object sender, EventArgs e)
{
    string newText = TitleText.Value;
    FindEnabled.Value = (newText != null & newText.Length > 0);
}

public void FindClick(object sender, EventArgs e)
{
    ICollection books = bookDepository.Find(TitleText.Value);
    IList bookListItems = BookListItems.Value;

    bookListItems.Clear();
    foreach ( string book in books )
    {
        bookListItems.Add(book);
    }
}

The client developer has to remember to use the funny property types, but this isn’t that much harder than, say Func. At least the names make some sense.
The .Value could get a little old, but I prefer having it on both the get and the set even over just on the set. I like having the strong-typing built in to the type, rather than forcing the client developer to do the conversion in a property.

On the downside, additional property types will have to be added to the framework by hand, but that shouldn’t come up too often. Also, the storage strategy for the properties is maybe a little complicated, but at least clients of the framework never have to deal with it directly. The observant among you will probably criticize the strategy because so far there’s no use for it. Bear with me. Next time I’ll show you how the strategy adds value.

Growing an MVVM Framework in 2003, part II – Properties

This is second post in a series on my experiences starting to grow an MVVM Framework in .NET 1.1.

Full source code can be found in my Google Code repository.

Last time, I introduced a tiny Windows Forms application and described my efforts to make a small MVVM framework for it. At the end of that post, we’d seen one way to use convention to bind View events to ViewModel event handlers.

Today I’ll talk about properties. It’s all very well to have a click on the “Find” button trigger the FindClick method on the ViewModel, but it’s useless unless we know what to look for. I needed a way to pass the Title.Text value to the ViewModel so it could use it for the search.
Then the FindClick method I showed last time would work:

public void FindClick(object sender, EventArgs e)
{
    ICollection books = bookDepository.Find(TitleText);
    BookListItems.Clear();
    foreach ( string book in books )
    {
        BookListItems.Add(book);
    }
}

A Failed Attempt

First I tried using Windows Forms binding, with lamentable results. I wish I’d saved the intermediate steps, as I was probably doing something wrong and could’ve solicited help. Still, whether it was due to a lack of experience on my part, or a flaw in the system, the bindings just wouldn’t work. I could bind bools and strings, but lists were right out.

A Proxy for Properties

I decided to rely on the storage objects that came with the View elements. This meant the ViewModel needed some way to proxy the properties on the View. Then a get or a set on the ViewModel object would flow right through, reading or writing the View’s values.
Here’s what I came up with:

public class BoundProperty: Property
{
    private object obj;
    private PropertyInfo propertyInfo;

    public BoundProperty(object obj, PropertyInfo property)
    {
        this.obj = obj;
        this.propertyInfo = property;
    }

    public override object Value
    {
        get { return propertyInfo.GetValue(obj, null); }
        set { propertyInfo.SetValue(obj, value, null); }
    }
}

Ignore the Property base class for a bit. An instances p of type BoundProperty can be used to get and set values on the proxied object obj like so:

p.Value = valueA;
object valueB = p.Value;

Not incredibly thrilling, but one can work with it. Using the .Value in order to access the value was a little cumbersome, so I added a little syntactic sugar in the Property base class:

public abstract class Property
{
    public abstract object Value { get; set; }

    public static implicit operator string(Property prop)
    {
        return (string) prop.Value;
    }

    public static implicit operator bool(Property prop)
    {
        return (bool) prop.Value;
    }

    public IList AsList()
    {
         return (IList) Value;
    } 
}

I really like the implicit operator functionality, which I’d never used before. I wish it could be used with interfaces, though. There’s probably a good reason why it can’t, but nothing comes to mind. Anyhow, I had to go another route for IList – the somewhat uninspiring AsList method. At this point, I was really missing generics.

Still, it’s nicer to be able to write

string myString = p1;
IList myList = p2.AsList();

instead of

string myString = (string) p1.Value;
IList myList = (IList) p2.Value;

Hooking up the Properties

This is pretty much the same as hooking up the events like the last time. All we have to do is define a field (yes, a field) of type Property in the ViewModel:

private Property titleText;

The ViewModelBase loops over all the Property fields and looks for View controls that have matching property names:

foreach ( FieldInfo field in PropertyFields() )
{
    FindPropertyToBindTo(allControls, field);
}

private void FindPropertyToBindTo(ArrayList allControls, FieldInfo field)
{
    foreach ( Control control in allControls )
    {
        if ( BindFieldToControl(control, field) ) { return; }
    }
}

private bool BindFieldToControl(Control control, FieldInfo field)
{
    string controlPropertyName = ControlAttributeName(control, field);
    if ( controlPropertyName == null ) { return false; }

    PropertyInfo controlProperty = control.GetType().GetProperty(controlPropertyName, myBindingFlags);
    if ( controlProperty != null )
    {
        field.SetValue(this, new BoundProperty(control, controlProperty));
    }
    return true;
}

Technically that’s it, but the rest of the ViewModel’s code is a little cleaner if we self encapsulate the field:

public string TitleText
{
    get { return titleText; }
    set { titleText.Value = value; }
}

Remarks

Once the infrastructure was in place, I really started enjoying developing the application. It was very liberating to add a new event handler just by writing a method with the right name and signature. And even adding access to a new property wasn’t so bad – writing the three lines of code to segregate the conversions and .Values was worth it to keep the event handler bodies nice and clean.

Next time, we’ll see how the design affected the form of the application’s unit tests.

Growing an MVVM Framework in 2003, part I – Event Handlers

This is the first post in a planned series on my experiences starting to grow an MVVM Framework in .NET 1.1.

Full source code can be found in my Google Code repository.

At the Day Job I usually work on web services, but I recently had the opportunity to write a customer-facing tool that had a GUI.

Previously, I expressed my excitement over the Rob Eisenberg  “Build Your Own MVVM framework” talk. Ever since, I’ve been dying to try my hand at an MVVM application. I wanted to create an application that

  • had testable logic, even in the GUI layer,
  • had no “codebehind” in the view, and
  • shunted the tedious wiring up of events and handlers into helpers (or a “framework”)

Unfortunately, the application was intended to work at our established customers’ sites, so I couldn’t depend on WPF, or even .NET 2.0 – it’s 1.1 all the way.

The Goal

I’ll demonstrate with a simpler app than the one from work, but will cover the the relevant concepts. For the purpose of this post, I’ll be writing a book-finding app. The user will be able to enter a substring to use to search a database; the matching entries will be displayed in a ListBox and when one of them is selected, some notes will be displayed in a TextBox.

BookFinder Mockup

I didn’t want to have to riddle my ViewModel with +=s just to be able to react to button presses and item selections from the view. I wanted to write something like:

public void FindClick(object sender, EventArgs e)
{
    ICollection books = bookDepository.Find(TitleText);
    BookListItems.Clear();
    foreach ( string book in books )
    {
        BookListItems.Add(book);
    }
}

and have the method run when the Click event on the Find button was raised. The method should use the value of the Text property of the Title TextBox to find a list of books and put them in the Items collection on the BookList ListBox.

Wiring up Event Handlers

I created a ViewModelBase class to handle all the infrastructure, so the BookListViewModel code could focus on app-related functions. The first thing ViewModelBase.BindToView does is seek out event handlers to bind to on the supplied View (which can be any Controller object):

ArrayList allControls = AllControlsDescendingFrom(View);
foreach ( MethodInfo handler in EventHandlers() )
{
    FindEventToListenTo(allControls, handler);
}

AllControlsDescendingFrom recursively looks through all the controls rooted at the View and returns them as a flat list. EventHandlers uses reflection to locate public methods on the ViewModel that have event-like signatures:

private IEnumerable EventHandlers()
{
    ArrayList eventHandlers = new ArrayList();
    foreach ( MethodInfo method in this.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public) )
    {
        if ( isEventHandler(method) )
        {
            eventHandlers.Add(method);
        }
    }
    return eventHandlers;
}

private bool isEventHandler(MethodInfo info)
{
    ParameterInfo[] parameters = info.GetParameters();
    return
        (info.ReturnType == typeof (void) &&
         parameters.Length == 2 &&
         parameters[0].ParameterType == typeof(object) &&
         (typeof(EventArgs)).IsAssignableFrom(parameters[1].ParameterType));
}

Note the last line. I’d originally just checked that the second parameter was of type EventArgs. This worked for many event types, like the Click event on a Button and the SelectedIndexChanged event on a ListBox, but failed to match others, such as a TextBox’s KeyPress event:

public delegate void KeyPressEventHandler(object sender, KeyPressEventArgs e)

FindEventToListenTo looks through the allControls list. If there’s a control with name Controlname and an event Eventname, it will bind to a handler named ControlnameEventname. For example method SearchClick would be hooked up to the Click event on a control called Search.

private void FindEventToListenTo(ArrayList allControls, MethodInfo handler)
{
    foreach ( Control control in allControls )
    {
        if ( ListenToEvent(control, handler) )
        {
            return;
        }
    }
}

private bool ListenToEvent(Control control, MethodInfo method)
{
    string eventName = ControlAttributeName(control, method);
    if ( eventName == null )
    {
        return false;
    }
    
    EventInfo eventInfo = control.GetType().GetEvent(eventName, BindingFlags.Instance | BindingFlags.Public);
    if ( eventInfo == null )
    {
        return false;
    }

    eventInfo.GetAddMethod().Invoke(control, new object[]
                  {
                    Delegate.CreateDelegate(eventInfo.EventHandlerType, this, method.Name)
                  });
    return true;
}

This is pretty straightforward, with two exceptions. Creating the delegate to wrap the ViewModel method was a little tricky – I had to reference the specific EventHandlerType that matched the event. Similarly to the EventArgs problem above, I’d originally tried to create an EventHandler, which failed for certain events.

The last piece is the ControlAttributeName method, which builds the desired attribute (in this case an event) name from a control and the ViewModel member that we want to bind to. The method assumes that the name of the ViewModel member (the handler) will start with the name of the control. If there’s a match, it returns the rest of the member name. Otherwise, null.
The name comparison ignores case, which wasn’t necessary to hook up method handlers, but proved to be useful when wiring up properties.

private string ControlAttributeName(Control control, MemberInfo viewModelMember)
{
    if ( viewModelMember.Name.ToLower().StartsWith(control.Name.ToLower()) )
    {
        return viewModelMember.Name.Substring(control.Name.Length);
    }
    return null;
}

What’s next?

After wiring the event handlers, the ViewModelBase binds to the View’s interesting properties. Details to follow.

Watch, even if you’re not building an MVVM App

I’m about two weeks behind the wave, but this week I found the time to watch Rob Eisenberg’s Mix 10 Build your own MVVM Framework talk (who says having the flu is all bad?).

It’s well worth the hour and twenty minutes. If you haven’t yet, grab a tea, fire up the video, and sit back. Seriously, I can’t describe how much I enjoyed it. My impressions, in no particular order:

  • The warning about needing MVVM experience may be overstated – I’ve never worked with MVVM (or GUIs, really), and only had it described to me by The Guy in the Next Cubicle, and I felt like I followed along well enough. If you know what the M, the V, and the VM are, that may be all you need.
  • Having computers perform repetitive tasks for humans is cool – we should try more of that.
  • Even if you don’t care about MVVM or GUI programming, the section about using .NET IEnumerables to implement Coroutines (starting at around minute 48) is worth the price of admission – this looks like an extremely powerful technique to (among other things) remove some of the complexity of performing aynchronous calls. I’m going to keep an eye out for places that this could help me.
  • I really liked the message that Mr. Eisenberg kept hitting – the mini-framework is (just?) a way of crystalizing existing conventions and making them work for you. This is a very powerful point – presumably you have conventions that you and your coworkers follow, so why not try to get more out of them? Perhaps incongruously, this reminds me a little of the strongest argument in favour of using whitespace for flow control in Python – in many languages (say C), we use braces to tell the compiler where a block begins and ends, and whitespace to tell the humans – why not use one mechanism for both? The mini framework does a similar thing – when we name classes SearchView and SearchViewModel, we do it so the programmers know how the classes are related, so why require an additional statement or constructor parameter or whatever to link them up? If the framework understands the convention, it can do the work for you.
  • The live presentation certainly helped to understand things – it was much easier for me to follow this than to try to understand Effectus from text and source, not to denigrate Ayende Rahien’s efforts.
  • Another point I enjoyed – the framework is there to make 90% of the cases easier. If it turns out that something needs to be a little different because it’s no performing well enough or something, you can do that too.
  • Somewhat tied to the previous point, but I can’t remember if it was mentioned – having a framework implement your conventions not only saves you work, but it can strengthen your conventions. If the easiest thing to do to get something to work is to follow a set of conventions, then people will follow the conventions – in addition to everything else, the framework can serve as a reminder to experienced developers and a teaching aid to the tyros.

One thing I’d like to see sometime, and this would likely be better-suited to a short book or long paper, would be the evolution of an application from frameworkless to frameworkful. Mr. Eisenberg kept stressing how the framework grew out of existing conventions in the Game Library application. I’d really like to see a case study – at what point is a convention recognized and the decision made to formalize it? Did everything happen at once, at the beginning (“we’ll call our classes BlahView and BlahViewModel, so we’ll need a ViewModelToViewHookerUpper”), or as development progressed (“this is the fifth button I’ve created that’s called Save and calls the Save method on the ViewModel – why can’t the computer know that’s what I want?”)?

Anyhow, don’t just listen to me. Watch for yourself.

Now I’m off to resist poring over the Day Job source code so see how we can fatten up our framework layer…