Recently, I had to implement validation on business objects in an already existing project. The validation should ensure that the different classes in the business object tier would validate them selves based on business rules. One of the rules on the Product class was that the Price property never must be negative and the Name property must be at least one character long.

For some reason I don’t know, none of these validation checks was made and I had to find a simple way to implement the checks without changing the original code too much. I’m a big fan of Rockford Lhotka’s CSLA.NET framework which has a nice way of doing validation, so I used that as an inspiration.

In the spirit of CSLA.NET I wanted the boolean read-only property IsValid, that tells whether or not the object is valid or not. I also wanted a read-only property called ValidationMessage, which tells what rules are broke and how to correct them.

The business objects didn’t have a base class, so I decided to create one and add as much of the validation code there. Here is that abstract class called ValidationBase:

using System;

using System.Text;

using System.Collections.Specialized;

 

public abstract class ValidationBase

{

 

  private StringDictionary _BrokenRules = new StringDictionary();

 

  /// <summary>

  /// Add or remove a broken rule.

  /// </summary>

  /// <param name="propertyName">The name of the property.</param>

  /// <param name="errorMessage">The description of the error</param>

  /// <param name="isBroken">True if the validation rule is broken.</param>

  protected void AddRule(string propertyName, string errorMessage, bool isBroken)

  {

    if (isBroken)

    {

      _BrokenRules[propertyName] = errorMessage;

    }

    else

    {

      if (_BrokenRules.ContainsKey(propertyName))

      {

        _BrokenRules.Remove(propertyName);

      }

    }

  }

 

  /// <summary>

  /// Reinforces the business rules by adding rules to the

  /// broken rules collection.

  /// </summary>

  protected abstract void Validate();

 

  /// <summary>

  /// Gets whether the object is valid or not.

  /// </summary>

  public bool IsValid

  {

    get

    {

      Validate();

      return this._BrokenRules.Count == 0;

    }

  }

 

  /// /// <summary>

  /// If the object has broken business rules, use this property to get access

  /// to the different validation messages.

  /// </summary>

  public string ValidationMessage

  {

    get

    {

      StringBuilder sb = new StringBuilder();

      foreach (string messages in this._BrokenRules.Values)

      {

        sb.AppendLine(messages);

      }

 

      return sb.ToString();

    }

  }


}

Then I hade to change all the business object so they derived from ValidationBase and implement the Validate() method on each of them. That’s all the work needed in order to start using the IsValid property. Here’s a dummy example of a derived class that uses the validation feature in its Save() method:

using System;

 

public class Product : ValidationBase

{

  #region Poperties

 

  private int _Price;

 

  public int Price

  {

    get { return _Price; }

    set { _Price = value; }

  }

 

  private string _Name;

 

  public string Name

  {

    get { return _Name; }

    set { _Name = value; }

  }

 

  #endregion

 

  #region Methods

 

  public void Save()

  {

    // Only save if the object is valid,

    // otherwise throw an exception.

    if (IsValid)

    {

      DoSomething();

    }

    else

    {

      throw new Exception(ValidationMessage);

    }

  }

 

  #endregion

 

  #region Validation

 

  /// <summary>

  /// Reinforces the business rules by adding rules to the

  /// broken rules collection.

  /// </summary>

  protected override void Validate()

  {

    AddRule("Price", "Price must be greater than or equal to 0", this.Price < 0);

    AddRule("Name", "Name must be set", string.IsNullOrEmpty(this.Name));

  }

 

  #endregion

}

It became a very simple implementation in the derived classes that didn’t demand any big changes to the original code.

It’s a good rule of thumb to overload the equality operators on classes. That ensures a correct comparison between to class instances of the same type. If you don’t, .NET automatically uses reflection and that is way slower than a custom implementation.

We all use the equality operators (“==”, “!=”) all the time and we expect them to be right every time. They are not!, but even if they were there is a good chance that you want to change them anyway. For instance, if your class has a unique Id property, then that property is the one that tells if two instances are the same. If you don’t overload the operators, you could have two instances with the same Id treated as two different instances.

First of all, you have to find out what makes two instances different. Let’s keep using the Id property example in an imaginary class called Foo. Then lets start overriding the GetHashCode() method so it returns the hashcode of the Id property.

/// <summary>

/// A uniquely key to identify this particullar instance of the class

/// </summary>

/// <returns>A unique integer value</returns>

public override int GetHashCode()

{

  return this.Id.GetHashCode();

}

Whenever the GetHashCode() method is called, it returns a unique integer value that represents the uniqueness of the class instance. Now we can use that method to overload the operators.

/// <summary>

/// Checks to see if two business objects are the same.

/// </summary>

public static bool operator ==(Foo first, Foo second)

{

  // Checks if the pointer in memory is the same

  if (Object.ReferenceEquals(first, second))

  {

    return true;

  }

 

  // Checks for null values

  if ((object)first == null || (object)second == null)

  {

    return false;

  }

 

  return first.GetHashCode() == second.GetHashCode();

}

 

/// <summary>

/// Checks to see if two business objects are different.

/// </summary>

public static bool operator !=(Foo first, Foo second)

{

  return !(first == second);

}

The reason why it is necessary to box the two Foo parameters (first, second) to type object, is to avoid an overflow exception.
 
We still need one more thing to be sure that we can compare two instances to each other, and that is by overriding the Equals() method. You can use the Equals() method or the operators to compare instances and they should always return the same result.

/// <summary>
///
Comapares this object with another
///
</summary>
///
<param name="obj">The object to compare</param>
///
<returns>True if the two objects as equal</returns>
public
override bool Equals(object obj)
{
  if (obj == null)
  {
    return false;
  }

  if (obj.GetType() == this.GetType())
  {
    return obj.GetHashCode() == this.GetHashCode();
 
}

  return false;
}

You can implement these methods on a base class so you won’t have to write it on all the derived classes. Because these methods uses GetHashCode() to compare two instances, it would be preferable to override that method in the derived classes if needed.