Quotation of the day! 2012-03-15

Science is the poetry of reality

Quotation of the day! 2012-03-08

If you see a switch statement you should think polymorphisms!

Quotation of the day! 2012-02-20

Never trust a programmer in a suit.

Quotation of the day! 2012-02-10

In the future, programming will be a basic course alongside reading and math.

The Cult of Done Manifesto

I hope this image is self-explaining :)

Quotation of the day!

Programming is like sex… one mistake and you support it forever!

[Programming Rules] Describe summited bugs in details

“Some fields should be read-only”… Is this a good description? If you can read in other minds, then it’s ok….. otherwise be more precise when submitting a bug report!
The rule is: Describe the bug in as many details as needed to be reproduced by software engineer. Attach some crash reports if possible.

Showing IDataErrorInfo for NULL objects

WPF provides, fairly easy to implement, possibility to validate entered data and notify user when something is incorrect. An example is available in MSDN, so I will skip further explanation how does this work…

Everything works like a charm till you validate data bounded to main object. For instance let’s examine code below:

public abstract class AbstractCity : ICity
{
    private string name;
    private Country country;
 
    public string Name
    {
        get { return name; }
        set
        {
            if (name != value)
            {
                name = value;
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("Name"));
            }
        }
    }
    public virtual Country Country
    {
        get
        {
           return country;
        }
        set
        {
            if (country != value)
            {
               country = value;
               ExecutePropertyChanged("Country");
            }
        }
    }
    public string this[string columnName]
    {
        get
        {
            switch (columnName)
            {
                case "Name":
                    return String.IsNullOrWhiteSpace(Name) ? "City name must be set" : String.Empty;
                case "Country":
                    return Country == null ? "Country must be set" : String.Empty;
                default:
                    return String.Empty;
            }
        }
    }
 
    public string Error
    {
        get { return this["Name"]; }
    }
 
    protected void ExecutePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
 
    public event PropertyChangedEventHandler PropertyChanged;
}
 
public class CityNullCountry : AbstractCity { }

and binding in XAML:

<TextBox  Grid.Column="1" Grid.Row="0" Text="{Binding Path=City.Name, ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox  Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" Width="250" Text="{Binding Path=City.Country.Code, Mode=OneWay, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" IsReadOnly="True"/>
<ComboBox Grid.Column="1" Grid.Row="1" HorizontalAlignment="Right" Width="100" SelectedItem="{Binding Path=City.Country}" ItemsSource="{Binding Path=Countries}" DisplayMemberPath="Code"/>
<TextBox  Grid.Column="1" Grid.Row="2" Text="{Binding Path=City.Country.Name, ValidatesOnDataErrors=True, NotifyOnValidationError=True, Mode=OneWay}" IsReadOnly="True"/>

in this code it is very easy validate and notify user when Name property in CityNullCountry object is NULL or empty. But there is no easy solution to validate City.Country.Name property. The reason is that Country object may not exists when City object is created.

So as up now we know that WPF needs Country class instance in order to validate it (using IDataErrorInfo in that class) and notify user when something is wrong. Some of you may ask, why I don’t check Country object in City class. The answer is simple. WPF validates bounded object and in that case it is Country object and it’s Name property. Text=”{Binding Path=City.Country.Name, ValidatesOnDataErrors=True, NotifyOnValidationError=True, Mode=OneWay}”. TextBox with such binding will check for IDataErrorInfo interface in Country class…. but Country object may be empty and nothing will be validated. User will be not aware of any errors at all.

So, my solution is fairly easy. I will simply provide an fake Country object when real object is NULL. Validation will run against my fake object and errors will popup in the user interface. One way to achieve that is to use Activator.CreateInstance() method. The whole mechanism implementation is showed below:

public class CityNullIsDefaultCountry : AbstractCity
{
    private Country country;
 
    protected DefaultsTable defaults = new DefaultsTable();
 
    public override Country Country
    {
        get
        {
            return defaults.GetObjectOrDefault(country, "Country");
        }
        set
        {
            if (country != value)
            {
                country = value;
                ExecutePropertyChanged("Country");
            }
        }
    }
}
 
public class DefaultsTable
{
    readonly Dictionary<string, object> defaults = new Dictionary<string, object>();
 
    public T GetObjectOrDefault<T>(T obj,  string propName) where T : class
    {
        if (obj != null)
            return obj;
 
        if (defaults.ContainsKey(propName))
            return (T)defaults[propName];
 
        T defaultObject = (T)Activator.CreateInstance(typeof(T));
 
        defaults.Add(propName, defaultObject);
 
        return defaultObject;
    }
}

DefaultsTable defaults = new DefaultsTable(); is responsible for providing fake object if it is NULL. When we set the Country property to some value, this value will be returned.

On of the challenges now is to determine what kind of object is returned when we access Country property on City class… I will discuss that somewhere in the future. In short: this can be determined by adding IsDefault flag and checking it.

Sample code for this example can by found here

kick it on DotNetKicks.com

[Programming Rules] Consider writing Unit Test for the bug you have fixed

Remember!
When you fix a bug and you feel that it may occur in the future, don’t waste time and write at least one Unit Test to check code against that bug.

Logging Exception with StackTrace

C# language has a great Exception Handling mechanism build-in. If something in not predictable during compile time developer can easily embed that piece of code in try{ (...) } catch{ (...) } and say “case closed”. Sample code taken from MSDN:

class ExceptionTest
{
    static double SafeDivision(double x, double y)
    {
        if (y == 0)
            throw new System.DivideByZeroException();
        return x / y;
    }
    static void Main()
    {
        // Input for test purposes. Change the values to see
        // exception handling behavior.
        double a = 98, b = 0;
        double result = 0;
 
        try
        {
            result = SafeDivision(a, b);
            Console.WriteLine("{0} divided by {1} = {2}", a, b, result);
        }
        catch (DivideByZeroException e)
        {
            Console.WriteLine("Attempted divide by zero.");
            //Logger.Error("Attempted divide by zero.")
        }
    }
}

Works like a charm…. but this was very simple scenario. In more advanced scenarios we – developers – would like to get some more feedback, then just a logged information like:Attempted divide by zero. In business application a lot of other factors in involved. So it is necessary to have proper feedback information when something goes wrong. I’ve also faced that problem. Not sufficient information was provided with the bug description and we were unable to reproduce and fix the bug.

At that moment I’ve decided to do the obvious step. Serialize Exception object and save in separate log file :D

Code that realizes my idea is showed below:

public class ExceptionXElement : XElement
    {
        public ExceptionXElement(Exception exception)
            : base(new Func<XElement>(() =>
            {
                if (exception == null)
                {
                    throw new ArgumentNullException("exception");
                }
                XElement root = new XElement
                  (exception.GetType().ToString());
 
                if (exception.Message != null)
                {
                    root.Add(new XElement("Message", exception.Message));
                }
 
                if (exception.StackTrace != null)
                {
                    root.Add
                    (
                      new XElement("StackTrace",
                        from frame in exception.StackTrace.Split('n')
                        let prettierFrame = frame.Substring(6).Trim()
                        select new XElement("Frame", prettierFrame))
                    );
                }
 
                if (exception.Data.Count > 0)
                {
                    root.Add
                    (
                      new XElement("Data",
                        from entry in
                            exception.Data.Cast<DictionaryEntry>()
                        let key = entry.Key.ToString()
                        let value = (entry.Value == null) ?
                          "null" : entry.Value.ToString()
                        select new XElement(key, value))
                    );
                }
 
                if (exception.InnerException != null)
                {
                    root.Add
                    (
                      new ExceptionXElement
                        (exception.InnerException)
                    );
                }
 
                return root;
            })())
        { }
    }

Code above is nicely wrapped in a function that saves XElement into single file.