Archive for the ‘Presentation’ Category

Assemblers with ConvertAll

Friday, September 18th, 2009

In most applications we have some kind of assembler classes, that create models used in the presentation layer:

public class EntityComboModelAssembler
{
   public List<ComboBoxModel> CreateComboBoxModels(IList<Entity> entities)
   {
      List<ComboBoxModel> list = new List<ComboBoxModel>();
      foreach (Entityentity in entities)
      {
         list.Add(new ComboBoxModel(entity, entity.Name));
      }
      return list;
   }
}

It is possible to write this code in 1 (one) line of code:

public class EntityComboModelAssembler
{
   public List<ComboBoxModel> CreateComboBoxModels(IList<Entity> entities)
   {
      return entities.AsList().ConvertAll(x => new ComboBoxModel(x, x.Name));
   }
}

We can also remove AsList method by using extension method that adds ConvertAll method to IList interface:

public static class IListExtensions
{
   public static List<TOut> ConvertAll<TIn, TOut>(this IList<TIn> source, Converter<TIn, TOut> converter)
   {
      return source.ToList().ConvertAll(converter);
   }
}

And the final code:

public class EntityComboModelAssembler
{
   public List<ComboBoxModel> CreateComboBoxModels(IList<Entity> entities)
   {
      return entities.ConvertAll(x => new ComboBoxModel(x, x.Name));
   }
}

INotifyPropertyChanged with PostSharp 1.5

Tuesday, September 15th, 2009

If you are doing WPF development, most likely you are tired of writing property implementations that raise PropertyChanged event manually:

public class MainWindowViewModel : ViewModel
{
    private string _message;

    public string Message
    {
        get
        {
            return _message;
        }
        set
        {
            _message = value;
            OnPropertyChanged("Message");
        }
    }

    // ...
}

PostSharp is a great tool to make such things simplier.

Let’s look at the specific ViewModel class that has a Message property that is bound to some UI element using XAML:

public class MainWindowViewModel : ViewModel
{
    [RaisePropertyChanged]
    public string Message { get; set; }

    // ...
}

Notice the RaisePropertyChanged attribute, which we’ll implement later.

Here’s our base ViewModel class that provides actual implementation of the INotifyPropertyChanged interface:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged
        = delegate { };

    public void OnPropertyChanged(string propertyName)
    {
        PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
    }
};

Finally the PostSharp attribute:

[Serializable]  // required by PostSharp
public class RaisePropertyChangedAttribute : OnMethodBoundaryAspect
{
    private string _propertyName;

    /// <summary>
    /// Executed at runtime, after the method.
    /// </summary>
    public override void OnExit(MethodExecutionEventArgs eventArgs)
    {
        ViewModel viewModel = (ViewModel)eventArgs.Instance;
        viewModel.OnPropertyChanged(_propertyName);
    }

    public override bool CompileTimeValidate(MethodBase method)
    {
        if (IsPropertySetter(method))
        {
            _propertyName = GetPropertyName(method);
            return true;
        }
        return false;
    }

    private static string GetPropertyName(MethodBase method)
    {
        return method.Name.Replace"set_", "");
    }

    private static bool IsPropertySetter(MethodBase method)
    {
        return method.Name.StartsWith("set_");
    }
};

Note that we are validating if the method is in fact a property only during compilation time using CompileTimeValidate method.

During compile time appropriate invocations of OnPropertyChanged method will be injected after every set operation applied to the Message property.