Sunday, April 1, 2007

Using System.Reflection

Ever since I read a great article about using the builtin reflection API in C#, I wanted to use it in a real life situation. The idea is that at runtime, you can list classes, get info about their methods, attributes, super class, ... and even make instances of them using the Activator class.

For our import application, which will load data from an Excel spreasheet to an SQL Server 2005 database, we wanted to give the user a scala of ways in which the console application could notify the user. We came up with the following diagram...


The Open methods will be fired first, in the console output class they won't do much but they could be responsible for initializing a stream, connecting to the mailserver...
The Format method is passed an OutputItem object, which contains message data and a category (error/success/default)...
The Close method would close streams, send a mail with all the notifications, contact a webservice...

Now at runtime, we will use reflection to detect all classes which implement the IOutputFormatter abstract class and they will be instantiated by our FormatterReflectionManager class. By default this class will enable all formatters and stack them up in a generic list, but the user can choose which Formatters should be used. The idea is similar to the Enterprise Library, we didn't use the EntLib because it's a really big library and we didn't want to bring in extra dependencies. Another reason why we didn't use EntLib is because we already use it in another project and because we wanted to experiment with System.Reflection...

public void ReflectOutputFormatters()
{
foreach (Type type in Assembly.GetCallingAssembly().GetTypes())
{
if (type.IsSubclassOf(typeof(IOutputFormatter)))
_formatters.Add((IOutputFormatter)Activator.CreateInstance(type));
}
}


This chunck of code will look for all classes the extend the superclass and add them to a Generic List.

No comments: