January 2011 - Posts

When doing testing, I tend to create an object mother for the items generated multiple times for specifications. Quite often these objects need to be a part of a collection. A neat way to do so is to leverage .NET params mechanism:

    public static IEnumerable<T> CreateCollection<T>(params T[] items)
    {
      return items;
    }

And usage is the following:

private static IEnumerable<IPAddress> addresses = CreateCollection(new IPAddress(123456789), new IPAddress(987654321));

In the previous post I showed an attempt to get rid of the magical strings. It worked great for a string property, but failed for the integer one as JR has reported. I decided to look into that, but this time around through TDD and this is what I found (besides the fact that going TDD way would definitely catch it).

When a string property is passed in, returned object is expected therefore there’s nothing complicated, it works. Though, when an integer (or any other type that is not a string) is passed in, .NET implicitly applies Convert() method.

imageimage

Therefore the code should be update:

 

class PropertyOf<T>
  {
    public static string Resolve(Expression<Func<T, object>> expression)
    {
      Expression candidate = null;

      if (expression.Body is UnaryExpression)
        candidate = (expression.Body as UnaryExpression).Operand;

      if (expression.Body is MemberExpression)
        candidate = expression.Body;

      return (candidate as MemberExpression).Member.Name;
    }
  }

Tests are quite simple:

    [Observation]
    public void Should_return_integer_property_name_as_is_within_the_containing_class()
    {
      PropertyOf<Dummy>.Resolve(x => x.IntegerProperty).Should_Be_Equal_To("IntegerProperty");
    }

    [Observation]
    public void Should_return_string_property_name_as_is_within_the_containing_class()
    {
      PropertyOf<Dummy>.Resolve(x => x.StringProperty).Should_Be_Equal_To("StringProperty");
    }

    private class Dummy
    {
      public int IntegerProperty { get; set; }
      public string StringProperty { get; set; }
    }

JR has put together a good introduction post into MVVM pattern. I love kick start examples that serve the purpose well. And even more than that I love examples that also can pass the real world projects check. So I took the sample code and refactored it slightly for a few aspects that a lot of developers might raise a eyebrow.

Michael has mentioned model (entity) visibility from view. I agree on that. A few other items that don’t settle are using property names as string (magical strings) and Saver class internal casting of a parameter (custom code for each Saver command).

Fixing a property names usage is a straight forward exercise – leverage expressions. Something simple like this would do the initial job:

class PropertyOf<T>
{
public static string Resolve(Expression<Func<T, object>> expression)
{
var member = expression.Body as MemberExpression;
return member.Member.Name;
}
}

With this, refactoring property names becomes an easy task, with confidence that an old property name will not stay in the code after property gets renamed. An updated Invoice would look like this:

public class Invoice : INotifyPropertyChanged
{
private int id;
private string receiver;

public event PropertyChangedEventHandler PropertyChanged;

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

public int Id
{
get { return id; }
set
{
if (id != value)
{
id = value;
OnPropertyChanged(PropertyOf<Invoice>.Resolve(x => x.Id));
}
}
}

public string Receiver
{
get { return receiver; }
set
{
receiver = value;
OnPropertyChanged(PropertyOf<Invoice>.Resolve(x => x.Receiver));
}
}
}

For the saver, I decided to change it a little so now it becomes a “view-model agnostic” command, one that can be used for multiple commands/view-models. Reason for this is the fact that on average UI has more than a single command. Updated Saver now accepts an action at the construction time and executes that action when command is exercised. No more black magic Smile

  internal class Command : ICommand
{
private readonly Action executeAction;

public Command(Action executeAction)
{
this.executeAction = executeAction;
}

public bool CanExecute(object parameter)
{
return true;
}

public event EventHandler CanExecuteChanged;

public void Execute(object parameter)
{
// no more black magic
executeAction();
}
}

Change in InvoiceViewModel is instantiation of Saver command and execution action for the specific command.

 public ICommand SaveCommand
{
get
{
if (saveCommand == null)
saveCommand = new Command(ExecuteAction);
return saveCommand;
}
set { saveCommand = value; }
}

private void ExecuteAction()
{
DisplayMessage = string.Format("Thanks for creating invoice: {0} {1}", Invoice.Id, Invoice.Receiver);
}

This way internal knowledge of InvoiceViewModel remains in InvoiceViewModel and Command (ex-Saver) is view-model agnostic.

Now the sample is not only a good introduction, but also has some practicality in it. My 5 cents on the subject.

Sample code MvvmSimple2.zip

Update 2011-01-12: I have addressed the null exception issue in part 2.

More Posts