Saturday, February 10, 2007

Mini Pattern: The Guard Method

This post proposes a standard way to implement and call method parameter validation logic.

Instead of writing out the method parameter validation code in each method over and over again we will centralize it in a static helper class. This static helper class will be reusable over different projects and will speed up writing method parameter validation code.

This is the way most of us write method parameter validation code:

public void MyPublicMethod(string name)
{
if(String.IsNullOrEmpty(name))
{
throw new ArgumentNullException("name");
}

// method impl...

}

Instead we now call out static helper class named Throw:

public void MyPublicMethod(string name)
{
Throw.IfArgumentNullOrEmpty(name, "name");

// method impl...
}

With a central place to write parameter validation code you can make it a little more elaborate than you would if you'd had to write it in each method seperately. Notice the implementation make a distinction between is null and is empty.

public static void IfArgumentNullOrEmpty(
string argument, string argumentName)
{
if (String.IsNullOrEmpty(argument))
{
IfArgumentNull(argument, argumentName);

throw new ArgumentException("Argument cannot be empty.", argumentName);
}
}

There is one drawback in using this method of performing method parameter validation. FxCop does not recognize that you are performing validation on these parameters and will insist that you do. I hope that the FxCop (Code Analysis) team at Microsoft will come up with a code attribute we can use to decorate our "method parameter validation" methods.

You'll notice this way of implementing validation logic does not work well with The Throw Method. I personally think that method parameter validation exceptions require less or no context information other than perhaps the parameter value itself.

Mini Pattern: The Throw Method

This post proposes a standard way to throw exceptions from a class and fill the Exception.Data dictionary with the class' context information.

.NET 2.0 introduced a Data dictionary on the Exception class. This dictionary is ideal for holding context information at the place were the Exception is thrown. In order to be able to reuse the logic across all methods of the class and still use the single line syntax "throw new Exception();" a private Throw method is added to the class.

private void Throw(Exception exception)
{
exception.Data.Add("Name", this.Name);
exception.Data.Add("ID", this.ID);
exception.Data.Add("CreationDate", this.CreationDate);
exception.Data.Add("UserName", this.UserName);

throw exception;
}

The Throw method takes the state of the class and stores it in the Data dictionary of the Exception about to be thrown. This data represents (some of) the context in which the exception occurred.

Use the Throw method in other methods of your class whenever throwing an exception is appropriate.

public void MyPublicMethod(string name)
{
if(String.IsNullOrEmpty(name))
{
Throw(new ArgumentNullException("name"));
}

// method impl.
}

Make sure that you write out the extra information contained in the Exception.Data dictionary to the event log (or other log target) when you catch the exception. It should provide you with a little bit of runtime information to help you hunt down any bugs.