Monday, December 5, 2011

Making your views thread safe, AOP style

One of the nice things of using a pattern like MVP, where the UI logic of your screens (views) is separated from the business logic of your application is that you have more flexibility to add framework level behavior, doing things right in only one place.

One common scenario we encounter in every application is the necessity to do operations in a different thread to the one of the UI, example of these operations are any that are going to be expensive, (e.g. a network/service call). Up to here all is good, but in the cases where we need to update our UI after the expensive operation finished we need to somehow marshal these calls into the UI thread.


The common way to do this is by using the Control.Invoke(Delegate method) method available in the Control class, so for example to marshal setting a property to our view, you would define it like this in your view

public class MyView: IMyView
{
    public string Message
    {
        get
        {
             Func lambda = () => tMessage.Text;
             return InvokeRequired 
                ? (string) Invoke(lambda) 
                : lambda();
        }
        set
        {
             Action lambda = () => tMessage.Text = value;
             if (InvokeRequired)
                  Invoke(lambda);
             else
                  lambda();
        }
    }
}

As I'm sure you see, this gets pretty old fast. It is a lot of code that needs to be repeated everywhere, even more it might be forgotten somewhere and hard to track back once it fails.

One way to prevent having to put this code is by doing this call in an aspect, as I'm using spring.net in our current project, I'll demonstrate it the spring way, but this can be done with any other library that supports some kind of AOP (e.g. Postsharp).

What we need to do is implement the IMethodInterceptor interface, as seen here:

public class UIThreadInterceptor: IMethodInterceptor
 {
  public object Invoke(IMethodInvocation invocation)
  {
   var control = invocation.This as Control;
   if (control == null)
   {
    Log.Warn("Aspect applied to non-control instance.");
    return invocation.Proceed();
   }

   Func<object> expression = invocation.Proceed;
   return control.InvokeRequired ? control.Invoke(expression) : expression();
  }
 }

Once we configure this, we can set our setter/getters in the normal way and the aspect will do the marshalling for us. There is one catch though, as spring.net proxies on winforms controls should be configured to work by inheritance, we need to declare the properties we want to marshal as virtual.

public class MyView: IMyView
{
    public virtual string Message
    {
        get { return tMessage.Text; }
        set { tMessage.Text = value; }
    }
}

This still is not enough, in fact, it is easier to forget the 'virtual' keyword than all the chunky code we had before, so I've created a custom test that checks that all classes implementing the IView interface, need to have all its members declared as virtual.

Test code here:
public bool TestMethodsOf(Type impl, Type @interface)
  {
   var valid = true;
   Console.WriteLine("Testing methods of {0}", impl.Name);

   foreach (var iface in impl.GetInterfaces().Where(i => @interface.IsAssignableFrom(i)))
   {
    var members = iface.GetMethods();

    foreach (var member in members)
    {
     var implMember = impl.GetMethod(member.Name, member.GetParameters().Select(c => c.ParameterType).ToArray());
     if (implMember == null)
      continue;

     if (implMember.IsVirtual && implMember.IsFinal)
     {
      Trace.WriteLine("Method " + impl.Name + "." + member.Name + " is not virtual");

      valid = false;
      continue;
     }

    }
   }
   return valid;
  }


Whoa, this post was longer than expected. Hope it helps somone!
Cheers



Read More......

Saturday, December 4, 2010

Registering definitions programmatically with Spring.net - Part 2 - Generic Definitions

As a continuation of my previous post, here is a short explanation of the same functionality described before but making use of type checking, so these are useful when you know the type you are implementing as opposed as the previous post.



So, here is the Definition class that takes care of the Generic types, is worth mentioning that the implementation of this interface is just a wrapper of the Type based Definition.

public interface IDefinition<T>
{
    IDefinition<T> Singleton();
    IDefinition<T> Prototype();

    IDefinition<T> StaticFactory<F>(Expression<Func<T>> call);
    IDefinition<T> Factory<F>(Expression<Func<F, T>> call);

    IDefinition<T> ConstructorArgument(object value);
    IDefinition<T> ConstructorArgument<D>();

    IDefinition<T> Property<V>(Expression<Func<T, V>> expression, V value);
    IDefinition<T> Property<D>(Expression<Func<T, D>> expression);
    IDefinition<T> Property(string propertyName, object value);
    IDefinition<T> Property<D>(string propertyName);
    IDefinition<T> AddAlias<A>();
}

And here are some tests that show how the API is consumed in this case:

Registering a type as Prototype.
[TestMethod]
public void RegisterSimplePrototypeGeneric()
{
     Context.Register<EmptyService>(d => d.Prototype());
     Verify.IsPrototype<EmptyService>();
}

or registering through a factory method;

[TestMethod]
public void RegisterWithFactoryGeneric()
{
     Context.Register<ServiceFactory>();
     Context.Register<ServiceWithConstructor>(d => d.Factory<ServiceFactory>(x => x.CreateService()));
   
      Verify.CanResolve<ServiceWithConstructor>();
}

or with dependencies through Setter properties;

[TestMethod]
public void RegisterWithSetterDependencyGeneric()
{
    Context.Register<Dependency>();
    Context.Register<ServiceWithSetterDependencies>(d => d.Property(c => c.Value, "value").Property(c => c.Dependency));

    var dependency = Verify.CanResolve<Dependency>();
    var service = Verify.CanResolve<ServiceWithSetterDependencies>();
   
    Assert.AreEqual("value", service.Value);
    Assert.AreSame(dependency, service.Dependency);
}

All these combinations can be combined as long as they represent something consistent with what you can do through spring configuration.

In next post I'll introduce the Sterotypes, and how they combine with the definitions to facilitate the declaration of several types that are similar.

If you feel curious the code is at the google code repository

'till the next post!
Read More......

Wednesday, December 1, 2010

Registering definitions programmatically with Spring.net

During the last couple of years I've been using Spring.net framework across different projects, and I must confess that I like it a lot, especially how it lets me write code that is clean and decoupled. Something that comes handy both for maintenance and unit testing.

But one of the things that bothers me, and many people, is having to deal with xml configuration, there are some Fluent Spring libraries spring around but none of them convinced me 100%, also it seemed to be something fun to dig into and get to learn a little more about how spring works, so I've started doing some research and found that spring already has an ObjectDefinitionBuilder which ensures the creation of valid definitions, I started to write some code to see where I could get.


After some testing I ended with these interfaces:

public interface IDefinition
 {
        IDefinition Singleton();
        IDefinition Prototype();

        IDefinition Factory(Type factoryType, string methodName);
        
        IDefinition ConstructorArgument(object value);
        IDefinition ConstructorArgument(Type referenceType);

        IDefinition Property(string propertyName, object value);
        IDefinition Property(string propertyName, Type dependencyType);
        IDefinition StaticFactory(Type factoryType, string methodName);
        IDefinition AddAlias(Type type);
        IDefinition AddAlias(string alias);
 }

as an entry point I defined the following extension method for the IApplicationContext interface

public static void Register(this IApplicationContext context, Type type, Func<IDefinition, object> definition = null)
        {
            if (definition == null)
                definition = c => c;

            using (var def = new Definition(context, type))
                definition(def);
        }

        public static void Register(this IApplicationContext context, Type type)
        {
           Register(context, type, null);
        }

and now some tests to see how that is used from the code,

[TestMethod]
public void RegisterSimpleSingleton()
{
    Context.Register(typeof(EmptyService), d => d.Singleton());
    Verify.IsSingleton<EmptyService>();
}

[TestMethod]
public void RegisterWithFactory()
{
     Context.Register(typeof(ServiceFactory));
     Context.Register(typeof(ServiceWithConstructor), d => d.Factory(typeof(ServiceFactory), "CreateService"));

     Verify.CanResolve<ServiceWithConstructor>();
}


I don't want to make this post long, if you feel curious you can dig through the code in here: google code repository

Some other things that I will explain in future posts and are already included in the google code repository is:

- Generic Type definitions: Same as code above but with generic methods
- Configuring Stereotypes: Scan all types of an assembly that fulfill an specific filter and define them. This was the real motivation of my research, an example could be, register all non-abstract types that implement the IPresenter interface, or get all types that implement an interface that has the [ServiceContract] attribute and register them with the ServiceHostFactory so they can be hosted in WCF, and the list goes on.

Read More......

Sunday, November 28, 2010

Binding to the opposite value of a boolean

In the previous post while I was preparing the example I wanted to bind the Enabled property of two buttons to a single boolean property, something like:

button1.DataBindings.Add("Enabled", _model, "IsTrue");
button2.DataBindings.Add("Enabled", _model, "!IsTrue");

where IsTrue is a boolean property of my _model variable, of course the second line doesn't work as binding only supports binding to properties, so based on this StackOverflow question, I've thrown some lines of codes to achieve something similar:

public class BooleanBinding: Binding
    {
        public BooleanBinding(string propertyName, object dataSource, string dataMember, bool oposite)
            : base(propertyName, dataSource, dataMember)
        {
            if (!oposite) 
                return;
            
            Format += SetOposite;
            Parse += SetOposite;
        }

        private static void SetOposite(object s, ConvertEventArgs e)
        {
            e.Value = !((bool) e.Value);
        }
    }

    public static class BindingExtensions
    {
        public static BooleanBinding Add(this ControlBindingsCollection @this, string propertyName, object dataSource, string dataMember, bool opposite)
        {
            var binding = new BooleanBinding(propertyName, dataSource, dataMember, opposite);
            @this.Add(binding);

            return binding;
        }
    }


The first class named BooleanBinding is a normal Binding with the addition that if the opposite parameter is set to true, there is some event handling on the Parse and Format methods to negate the current `real` boolean value.

The second class is just a helper extension method so we can add a BooleanBinding through the Add method in the Control.Databindings collection.

Here is some example usage in a form that has 2 buttons and 2 checkboxes:
public partial class Form1 : Form
    {
        private Model _model;
        public Form1()
        {
            InitializeComponent();
            _model = new Model();

            button1.DataBindings.Add("Enabled", _model, "IsTrue");
            button2.DataBindings.Add("Enabled", _model, "IsTrue", opposite: true);

            checkBox1.DataBindings.Add("Checked", _model, "IsTrue");
            checkBox2.DataBindings.Add("Checked", _model, "IsTrue", opposite: true);       
        }

        private void button_Click(object sender, EventArgs e)
        {
            _model.IsTrue = !_model.IsTrue;
        }
    }

Consider that if you click on the checkboxes there is a problem with the databinding that is not related to this solution, and is nicely explained in this post: http://turbulentintellect.blogspot.com/2008/07/surviving-winforms-databinding.html

Source code for the example can be found here!

Read More......

Saturday, November 27, 2010

Redefining bound columns in Infragistic's UltraWinGrid

This week I had to implement a tree like grid in windows forms, ideally these were my wishes:

  1. I wanted to make usage of the bindings features of this grid, in other words, maintaining my model synchronized automatically by the grid
  2. Be it tree like because I need to bind to a recursive model (multiple nested bands of different model types)
  3. Some of these bands can be edited directly in the grid, and others that are more complex are edited through other form, so some bands are editable and others are read only
  4. Change the form (including the grid) from readonly to editable mode and back, putting every cell in editable doesn't cut it for me, because as the point just above mentions, some of my fields are never editable.


I had some experience with infragistics, but only with the web grid so probably some of the things I'm doing could be done easier by one of the multiple options in the grid that I couldn't find while I was researching about this, so if anyone knows how to do something in an easier way I would be glad to know it!


So, from my research and tests, when you assign a datasource to the UltraWinGrid there is no -direct- way of telling it what columns to show or hide, it will show everything available in the datasource you provide, this is far from ideal in my case, e.g. my model classes have "Id" columns or other columns that my client has specified he doesn't want to see in the grid. So if you want to hide or change something on the grid's layout, you should do it on the InitializeLayout event.

After playing a little with the layout in that event, I realized that it was a lot of work and the code wasn't very elegant, so I've decided to create an abstraction that could help me with this problem, and also be able to reuse in other screens where I know I will need the same. I've started thinking on how I would like to use this new abstraction and ended with something like this:
new UltraGridBandLayout<MyModelClass>()
                .AddColumn("Unbound Column", configuration: c => c.CellActivation = Activation.NoEdit)
                .AddColumn(m => m.Description)
                .AddColumn(m => m.OtherColumn)
                //etc
                .AddDropDownListColumn(m => m.Aggregation, AggregationsList);

So using Resharper, I just went ahead and created the class structure and implemented the methods, I ended creating two objects, one is the UltraGridBandLayout, where I keep the order of things I've added, and a ColumnDefinition that is in charge of configuring a UltraGridColumn, this will allow me in the future to add new ColumnDefinition implementations if I need to add a Column stereotype different than the current one, like a ButtonColumnDefinition, etc.

here is the code for these two classes:

public class UltraGridBandLayout<T>
    {
        public IList<ColumnDefinition> Definitions { get; set; }

        public UltraGridBandLayout()
        {
            Definitions = new List<ColumnDefinition>();
        }

        public void ApplyTo(UltraGridBand band)
        {
            var columns = band.Columns.Cast<UltraGridColumn>();
            
            //hide all columns by default
            foreach (var column in columns)
                column.Hidden = true;
            
            for (int i = 0; i < Definitions.Count; i++)
            {
                var definition = Definitions[i];
                //find the column
                var column = columns.FirstOrDefault(c => c.Key == definition.Key);

                if (column == null) //if no bound column exists, then add an unbound one
                    column = band.Columns.Add(definition.Key);

                column.Header.VisiblePosition = i; //set the position where this column should be
                definition.ApplyTo(column); //apply extra settings 
            }
        }

        public UltraGridBandLayout<T> AddColumn(Expression<Func<T, object>> expression, string caption = null, Action<UltraGridColumn> configuration = null)
        {
            return AddColumn(expression.MemberName(), caption, configuration);
        }

        public UltraGridBandLayout<T> AddColumn(string key, string caption = null, Action<UltraGridColumn> configuration = null)
        {
            Definitions.Add(new ColumnDefinition(key, caption, configuration));
            return this;
        }

        public UltraGridBandLayout<T> AddDropDownListColumn(Expression<Func<T, object>> expression, IValueList list, string caption = null, Action<UltraGridColumn> configuration = null)
        {
            Action<UltraGridColumn> action = c =>
                                                 {
                                                     c.ValueList = list;
                                                     c.Style = ColumnStyle.DropDownList;
                                                 };


            return AddColumn(expression, caption, configuration == null
                                                      ? action
                                                      : c => { action(c); configuration(c); });
        }
    }

    public class ColumnDefinition
    {
        public string Key { get; set; }
        public string Caption { get; set; }
        public Action<UltraGridColumn> Configuration { get; set; }

        public ColumnDefinition(string key, string caption = null, Action<UltraGridColumn> configuration = null)
        {
            Key = key;
            Caption = caption ?? key;
            Configuration = configuration;
        }

        public void ApplyTo(UltraGridColumn column)
        {
            column.Header.Caption = Caption;
            column.Hidden = false;
            column.CellActivation = Activation.AllowEdit;

            if (Configuration != null)
                Configuration(column);
        }
    }


The idea here is that I can switch from this layout to other layout just by calling the ApplyTo method and passing the band I want to modify. Here is an example of the working solution:

public Form1()
        {
            #region dummy data
            Aggregations.Add(new AggregationModel() {Description = "Max", Id = 1});
            Aggregations.Add(new AggregationModel() {Description = "Min", Id = 2});
            Aggregations.Add(new AggregationModel() {Description = "Count", Id = 3});

            Operations.Add(new OperationModel() { Description = "Add", Id = 1});
            Operations.Add(new OperationModel() { Description = "Substract", Id = 2});
            Operations.Add(new OperationModel() { Description = "Multiply", Id = 3});
            Operations.Add(new OperationModel() { Description = "Divide", Id = 4});

            Data.Add(new RuleGroupModel()
                         {
                             Id = 1,
                             Description = "Rule Group 1",
                             Aggregation = Aggregations.ElementAt(2),
                             Groups = new List<RuleGroupModel>
                                          { new RuleGroupModel()
                                                  {
                                                      Id = 2,
                                                      Aggregation = Aggregations.ElementAt(1),
                                                      Description = "Child Rule Group 1",
                                                      Rules = new List<RuleModel>()
                                                                  {
                                                                      new RuleModel()
                                                                          {
                                                                              Id = 1,
                                                                              Name = "Rule 1",
                                                                              Operation = Operations.ElementAt(3)
                                                                          },
                                                                      new RuleModel()
                                                                          {
                                                                              Id = 1,
                                                                              Name = "Rule 2",
                                                                              Operation = Operations.ElementAt(1)
                                                                          },
                                                                      new RuleModel()
                                                                          {
                                                                              Id = 1,
                                                                              Name = "Rule 3",
                                                                              Operation = Operations.ElementAt(2)
                                                                          },
                                                                      new RuleModel()
                                                                          {
                                                                              Id = 1,
                                                                              Name = "Rule 4",
                                                                              Operation = Operations.ElementAt(3)
                                                                          }
                                                                  }
                                                  }
                                          }
                         });

            Data.Add(new RuleGroupModel() { Id = 3, Description = "Empty Group", Aggregation = null});
            #endregion

            InitializeComponent();

            bSetReadonly.Enabled = true;
            bSetEditable.Enabled = false;

            //create value lists for infragistics
            InitializeValueLists();
            //band layout initialization
            InitializeLayouts();

            ultraGrid1.DisplayLayout.MaxBandDepth = 5;
            ultraGrid1.InitializeLayout += InitializeLayout;
            ultraGrid1.DataSource = Data;
        }

        private void InitializeLayouts()
        {
            RuleBandLayout = new UltraGridBandLayout<RuleModel>() //not editable band
                .AddColumn(m => m.Name, configuration: c => c.CellActivation = Activation.NoEdit)
                .AddDropDownListColumn(m => m.Operation, OperationsList, configuration: c => c.CellActivation = Activation.NoEdit);

            RuleGroupBandLayout = new UltraGridBandLayout<RuleGroupModel>()
                .AddColumn(m => m.Description)
                .AddDropDownListColumn(m => m.Aggregation, AggregationsList);
        }

        private void InitializeValueLists()
        {
            OperationsList = new ValueList();
            foreach (var operation in Operations)
                OperationsList.ValueListItems.Add(operation, operation.Description);

            AggregationsList = new ValueList();
            foreach (var aggregation in Aggregations)
                AggregationsList.ValueListItems.Add(aggregation, aggregation.Description);
        }


        void InitializeLayout(object sender, InitializeLayoutEventArgs e)
        {
            SetLayout(e.Layout);
        }

        private void SetLayout(UltraGridLayout layout)
        {
            var bands = layout.Bands.Cast<UltraGridBand>();
            
            //apply our layout to the auto generated bands
            foreach (var band in bands)
                switch (band.Key)
                {
                    case "Rules":
                        RuleBandLayout.ApplyTo(band);
                        break;
                    default:
                        RuleGroupBandLayout.ApplyTo(band);
                        break;
                }
        }

        private void bSetReadonly_Click(object sender, EventArgs e)
        {
            var columns = ultraGrid1.DisplayLayout.Bands.Cast<UltraGridBand>().SelectMany(b => b.Columns.Cast<UltraGridColumn>());

            foreach (var column in columns)
                column.CellActivation = Activation.NoEdit;

            bSetReadonly.Enabled = false;
            bSetEditable.Enabled = true;
        }

        private void bSetEditable_Click(object sender, EventArgs e)
        {
            SetLayout(ultraGrid1.DisplayLayout);
            bSetReadonly.Enabled = true;
            bSetEditable.Enabled = false;
        }

Here is the download link if anyone would like to see it working; bear in mind that you will need the infragistics dlls installed for it to run!

Read More......

Friday, November 19, 2010

ICommand and CommandManager for Windows Forms

At work we are putting together a prototype for Winforms, as we have some heavy use of spring in other components of the system, we were looking for some existing UI framework that could integrate nicely with it.

After some back and forth we decided to go with Prism. Although it is meant for WPF solutions, most of it components can be adapted to work with windows forms (see here on how to do it). After some development we thought it would be nice to also have Commands so we could decouple actions from the PresentationModels, and update the UI controls dependind on if the command is in a state that can be executed or not.

So, first step was to create the ICommand interface, pretty much as the one in WPF.
public interface ICommand: INotifyPropertyChanged
    {
        string Name { get; }
        bool Enabled { get; }
        void Execute();
    }

Note the INotifyPropertyChanged interface in the command, this interface is meant so we can throw the PropertyChanged event when the Enabled property value changes in the specific command implementation. The problem is that event is not going to be raised on its own, and here is when the CommandManager comes into play.

The responsibilities of the CommandManager are:
- Entry point to bind a IComponent to a ICommand
- Query the binded commands to see if they changed.

Here is the code:
public class CommandManager: Component
    {
        private IList<ICommand> Commands { get; set; }
        private IList<ICommandBinder> Binders { get; set; }

        public CommandManager()
        {
            Commands = new List<ICommand>();

            Binders = new List<ICommandBinder>
                          {
                              new ControlBinder(),
                              new MenuItemCommandBinder()
                          };

            Application.Idle += UpdateCommandState;
        }

        private void UpdateCommandState(object sender, EventArgs e)
        {
            Commands.Do(c => c.Enabled);
        }

        public CommandManager Bind(ICommand command, IComponent component)
        {
            if (!Commands.Contains(command))
                Commands.Add(command);

            FindBinder(component).Bind(command, component);
            return this;
        }

        protected ICommandBinder FindBinder(IComponent component)
        {
            var binder = GetBinderFor(component);

            if (binder == null)
                throw new Exception(string.Format("No binding found for component of type {0}", component.GetType().Name));
            
            return binder;
        }

        private ICommandBinder GetBinderFor(IComponent component)
        {
            var type = component.GetType();
            while (type != null)
            {
                var binder = Binders.FirstOrDefault(x => x.SourceType == type);
                if (binder != null)
                    return binder;

                type = type.BaseType;
            }

            return null;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
                Application.Idle -= UpdateCommandState;
           
            base.Dispose(disposing);
        }
    }

    public static class Extensions
    {
        public static void Do<T>(this IEnumerable<T> @this, Func<T, object> lambda)
        {
            foreach (var item in @this)
                lambda(item);
        }
    }

The remaining classes referenced are used to apply the bindings to the specific set of controls.

public abstract class CommandBinder<T> : ICommandBinder where T: IComponent
    {
        public Type SourceType
        {
            get { return typeof (T); }
        }

        public void Bind(ICommand command, object source)
        {
            Bind(command, (T) source); 
        }

        protected abstract void Bind(ICommand command, T source);
    }
 
    public class ControlBinder: CommandBinder<Control>
    {
        protected override void Bind(ICommand command, Control source)
        {
            source.DataBindings.Add("Enabled", command, "Enabled");
            source.DataBindings.Add("Text", command, "Name");
            source.Click += (o, e) => command.Execute();
        }
    }

    public class MenuItemCommandBinder : CommandBinder<ToolStripItem>
    {
        protected override void Bind(ICommand command, ToolStripItem source)
        {
            source.Text = command.Name;
            source.Enabled = command.Enabled;
            source.Click += (o, e) => command.Execute();

            command.PropertyChanged += (o, e) => source.Enabled = command.Enabled;
        }
    }


Example usage, create a forms add two Buttons and two ToolStripMenuItems in a Menu:
public partial class Form1 : Form
    {
        private CommandManager commandManager;

        public ICommand CommandA { get; set; }
        public ICommand CommandB { get; set; }

        public bool condition;

        public Form1()
        {
            InitializeComponent();

            commandManager = new CommandManager();
           
            CommandA = new DelegateCommand("Command 1", OnTrue, OnExecute);
            CommandB = new DelegateCommand("Command 2", OnFalse, OnExecute);

            commandManager.Bind(CommandA, button1);
            commandManager.Bind(CommandB, button2);

            commandManager.Bind(CommandA, command1ToolStripMenuItem);
            commandManager.Bind(CommandB, command2ToolStripMenuItem);
        }

        private bool OnFalse()
        {
            return !condition;
        }

        private bool OnTrue()
        {
            return condition;
        }

        private void OnExecute()
        {
            condition = !condition;
        }
    }

ok, this was a long post to start! but hope it helps someone!

download here.

Read More......