Showing posts with label Reflection. Show all posts
Showing posts with label Reflection. Show all posts

Thursday, December 24, 2009

Powershell like command line arguments in a C# Console Application

Source Code: http://www.box.net/shared/5l587aig4k

Here at work, we use Powershell to script some automated integration tests. Sometimes, simple scripts aren't enough, and we need to resort to writing Cmdlets. For the purpose of this blog post, all you really need to know about Cmdlets is that they're basically a C# class that's invoked from the Powershell command line. What I thought was really cool with Cmdlets, is the way it deals with command-line arguments.

Basically, there's a ParameterAttribute that you put on your properties, and those properties then get set from the command line. Here's a simple example:



public class MyCmdlet : Cmdlet
{
[Parameter]
public int IntArg { get; set; }
}



Then from the Powershell command line you would do something like this:

PS>MyCmdlet -IntArg 100

And then within your Cmdlet class, your IntArg property will automatically be set to 100.

It then dawned on me, we have many Console apps at work that each have their own way of parsing the arguments. Now I know there are many command line parsers out there, but I thought, wouldn't be be cool if we can have the kind of syntax for invoking Console applications just like Powershell does.

I won't explain all of the code, you can download it at the bottom of this post, and dig in yourself, but I'll just highlight a few points. Firstly, this is how you can use this library:

Say you have an application, that you need to pass in different characteristics of a person. Things like, Name, Age, Height and Email Address, you'd want to be able to invoke the application like this:

MyConsoleApp.exe -Name "Alex Friedman" -Age 27 -Height 69.5 -EmailAddress "a.friedman07@gmail.com"

First you'd need to create a Person class to represent all the command line arguments:



internal class Person
{
[Parameter]
public string Name { get; set; }

[Parameter]
public int Age { get; set; }

[Parameter]
public double Height { get; set; }

[Parameter(Mandatory=true)]
public string EmailAddress { get; set; }
}


Then, in your main method, you'd do this:



ArgsSetter<Person> argsSetter = new ArgsSetter<Person>(args);
Person person = argsSetter.BuildParameterObject();


And that's it. Your person object will have all the properties set. The thing to note here is that this library can deal with all primitive types including strings. Remember, all arguments come in as a string, even the number 27 for example gets passed in as the string representation of "27", yet it gets converted for you automatically to an int.

A few other things to note, is the error handling. I didn't implement extensive validation in this library. What I did implement was two things. First, there's an IValidator interface that does some error checking for fatal errors; errors that would prevent from even attempting to parse. I provide a DefaultValidator that checks that there are an even number of elements in the args array. You can think of the command line arguments as a Key-Value pair; the key being the argument name, and the value being the argument value. Therefore, if there's an odd number of args, something isn't right. Also, it makes sure to check that arguments begin with a "-". If that's not enough, you can implement your own IValidator.

The second part of error handling, is to make sure that the values are correct, and that the Mandatory arguments have been provided. To get that information you do something like this:



foreach (var error in setter.Errors)
{
Console.WriteLine("Paramname: {0}, Error: {1}", error.ArgumentName, error.ErrorType);
}


The ArgsSetter class has an Errors collection that gives you all the errors that occurred.

Here's a link to the source code. It contains the actual library, as well as some unit tests:
http://www.box.net/shared/5l587aig4k

That's pretty much all there is to it. Feel free to download the source code and mess with it. I'd like to stress the point that there's alot more that can be done with this, and if you do use this and add something, feel free to drop me an email. Also, any constructive criticism is always welcome. Enjoy!

Monday, June 29, 2009

Factory Pattern with Attributes. Get rid of the ugly switch / case.

Source Code: http://www.box.net/shared/2yh2r6l91c

A very common design pattern used in Object Oriented Programming, is the Factory Pattern. The purpose of this post isn't to explain the factory pattern or why it's useful, rather I want to show a simple way to eliminate a giant switch / case found in many factory pattern implementations. For some good reading on the Factory Pattern, I suggest reading these two articles:

Wikipedia : http://en.wikipedia.org/wiki/Factory_method_pattern

MSDN : http://msdn.microsoft.com/en-us/library/ms954600.aspx

To demonstrate a simple example of the Factory Pattern, I've created a few classes. First, I created a base Vehicle class that looks something like this:



public abstract class Vehicle
{
public virtual int TopSpeed
{
get
{
return 150;
}
}

public abstract int Wheels
{
get;
}

public override string ToString()
{
return String.Format("A {0} has {1} wheels, and a top speed of {2} MPH."
, this.GetType().Name, this.Wheels, this.TopSpeed);
}
}


Just a base class that has one virtual property, one abstract property, and it overrides ToString. Then, I've created 4 subclasses:



public class Car : Vehicle
{
public override int Wheels
{
get { return 4; }
}
}

public class SuperCar : Car
{
public override int TopSpeed
{
get
{
return 200;
}
}
}

public class Truck : Vehicle
{
public override int Wheels
{
get { return 18; }
}
}
public class Motorcycle : Vehicle
{
public override int Wheels
{
get { return 2; }
}

public override int TopSpeed
{
get
{
return 190;
}
}
}


So we have Vehicle, Car, SuperCar, Truck and Motorcycle. Now, say we wanted to create a Factory that returns us the correct Vehicle class based on an enum that we'd supply. So let's create an enum:



public enum VehicleType
{
Car,
SuperCar,
Truck,
Motorcyle
}


We'd then have a method that looks something like this:



public static Vehicle GetVehicle(VehicleType vehicle)
{
switch (vehicle)
{
case VehicleType.Car:
return new Car();
case VehicleType.SuperCar:
return new SuperCar();
case VehicleType.Truck:
return new Truck();
case VehicleType.Motorcyle:
return new Motorcycle();
default:
return null;
}
}

Well, this is all nice, and works fine, but imagine a scenario where you may have many many subclasses. This switch statement would get huge, and unmaintainable quickly. Imagine then that new subclasses come along, you'd have to first update the enum, and then remember to update this switch / case. Well, I think there's a better way to do this.

The premise is simple; create an attribute that has one property called Type. This attribute will go on the enum, and will represent which type should be instantiated for each value of the enum. So, let's first create the Attribute class:



public class VehicleInfoAttribute : Attribute
{
private Type type;

public VehicleInfoAttribute(Type type)
{
this.type = type;
}

public Type Type
{
get
{
return this.type;
}
}
}


Nothing fancy, just a simple attribute that will house the Type to be created. Now, let's go back to our enum, and decorate the values with the correct attributes:



public enum VehicleType
{
[VehicleInfo(typeof(Car))]
Car,

[VehicleInfo(typeof(SuperCar))]
SuperCar,

[VehicleInfo(typeof(Truck))]
Truck,

[VehicleInfo(typeof(Motorcycle))]
Motorcyle
}


Now, each enum has an attribute that tells us which type to be instantiated for that type. Now, the fun part. The reflection bit in the factory method itself:

First, I've created an extension method for enum's that helps with getting custom attributes off of enum values:



public static class Extensions
{
public static T GetAttribute<T>(this Enum enumValue)
where T : Attribute
{
FieldInfo field = enumValue.GetType().GetField(enumValue.ToString());
object[] attribs = field.GetCustomAttributes(typeof(T), false);
T result = default(T);

if (attribs.Length > 0)
{
result = attribs[0] as T;
}

return result;
}
}


This allows you to do something like this:

MyCustomAttribute a = myEnumValue.GetAttribute<MyCustomAttribute>();

Now, we have all the pieces in place to write the Factory Method:



public static Vehicle GetVehicle(VehicleType vehicle)
{
var vehicleAttribute = vehicle.GetAttribute<VehicleInfoAttribute>();
if (vehicleAttribute == null)
{
return null;
}

var type = vehicleAttribute.Type;
Vehicle result = Activator.CreateInstance(type) as Vehicle;

return result;
}


First we call our extension method to get the attribute value for the enum passed in. Then, we use the handy Activator.CreateInstance() to create an object of that type.

To test it out, we can write a quick app:



static void Main()
{
Vehicle v = VehicleFactory.GetVehicle(VehicleType.Truck);
Console.WriteLine(v);
}


This will output:

A Truck has 18 wheels, and a top speed of 150 MPH.

Using this approach, yields two benefits. First, you no longer have a giant ugly switch / case. Secondly, if you ever have a case where another subclass is added, you just add another enum value (which you'd have to do anyway if you were using the switch / case), slap on the attribute, and you're done. The Factory method doesn't need to change at all.

Wednesday, June 3, 2009

Lesson learned....RTFM!

A few weeks ago, I was tasked with writing a site map generator for our new site at work that uses ASP.NET MVC. When using ASP.NET MVC Controllers have "Actions" that map to URL's. For the sake of this blog point, all that's important to know is that generally Actions are methods that return an ActionResult object. So, the idea was, in order to generate the site map correctly, I would use reflection to inspect the entire assembly, and any method that returned an ActionResult would be entered into the site map with the correct XML.

The catch however was that in many instances, the return type of our Action's weren't actually ActionResult objects, but rather classes the derived from ActionResult. (Some that are built into ASP.NET MVC and some custom ones.) So, I quickly realized I needed a method that you can pass in a type, along with another type, and the method would tell you if anywhere up the inheritance chain, type1 inherits from type2.

My first thought was "Perfect! I'll just use recursion!" This quickly got me excited, because it's not every day you get to use recursion in a useful piece of production code, much less when it came to reflection. So, I ended up writing an extension method that crawls up the inheritance chain recursively and it worked perfectly. Here's the code:

public static class TypeExtensions
{
public static bool InheritsFrom(this Type type, Type baseType)
{
if (baseType == null || type == null)
{
return false;
}

if (type.BaseType == baseType)
{
return true;
}

return type.BaseType.InheritsFrom(baseType);
}
}


Basically, the Type class has a handy property called BaseType which basically gives you the BaseType (duh!). If the Type is object, then BaseType is null, in which case we know we've reached the top of the inheritance chain, and we're done. To test this method out, let's whip up some demo code:



public class MyMemoryStreamBase : MemoryStream
{

}

public class MyMemoryStreamChild : MyMemoryStreamBase
{

}

public class MyMemoryStreamGrandChild : MyMemoryStreamChild
{

}
Basically, I've created a nice Inheritance chain that goes up to MemoryStream -> Stream -> MarshalByRefObject and finally object. Here's how you can test it:


Type type = typeof(MyMemoryStreamGrandChild);
bool result = type.InheritsFrom(typeof(MarshalByRefObject));
Console.WriteLine(result);

If you run this, the result will be True, proving that my cute little method worked, and I was all happy.

Fast forward a few weeks, and while browsing StackOverflow, I came across a question regarding reflection and BaseType's when some dude posts a link to this:

Type.IsSubClassOf(..)

Yeah, that's right! It's built right into the .NET Framework! Now obviously it's impossible to know of every method in the framework, but as soon as I thought of the need, and that it involved recursion, I simply whipped out Visual Studio and started coding, without actually taking a moment and thinking, hey research this first! You can't be the FIRST person to come across this very issue!

Feeling completely beat, I was just curious at this point as to how it's implemented in the Framework. Were they also using recursion, or did they have some other ingenious way of doing this. Well here's how they did it:



public virtual bool IsSubclassOf(Type c)
{
Type baseType = this;
if (baseType != c)
{
while (baseType != null)
{
if (baseType == c)
{
return true;
}
baseType = baseType.BaseType;
}
return false;
}
return false;
}

Yea, no recursion, just a simple while loop. At this point, I was just curious in general as to which method is quicker. So, some quick benchmarks:




public void CompareMethodsSpeed()
{
Stopwatch watch = new Stopwatch();
Type type = typeof(MyMemoryStreamGrandChild);
Type baseType = typeof(MarshalByRefObject);
watch.Start();
for (int i = 0; i < 100000; i++)
{
type.InheritsFrom(baseType);
}
watch.Stop();
Console.WriteLine("My way took: {0} ticks.", watch.ElapsedTicks);

watch.Reset();

watch.Start();
for (int i = 0; i < 100000; i++)
{
type.IsSubclassOf(baseType);
}
watch.Stop();
Console.WriteLine("Their way took: {0} ticks.", watch.ElapsedTicks);
}


Then I ran this one my machine and the results were:

My way took: 107433 ticks.
Their way took: 41684 ticks.

So yea, I got my butt whooped!! I'll chalk this one up to experience.

Moral of the story? Two things. First, not just because you CAN do it with recursion, does that mean you SHOULD do it that way. Second, RTFM!! Chances are, MS has more time to test various ways of doing certain things, so double check that something is in the Framework before rolling your own.

The only one thing I'll say in my (somewhat weak) defense is that InheritsFrom is a MUCH better name for this method than IsSubslassOf IMO. So yea, name your methods better MS!!

Wednesday, March 25, 2009

Cool IEnumberable extension method. Useful in ASP.NET MVC

So recently at work we started revamping our site and we've decided to use ASP.NET MVC. I'm not going to cover ASP.NET MVC in this blog post (hopefully in the future) but in short, it's Microsoft's new Web Framework that doesn't use WebForms. No more postbacks for every little thing! Woohoo! However, without WebForms, that means no more ASP.NET controls. Therefore, it was useful for us in a few places to be able to generate an HTML table from a collection of various different objects. So, I ended up writing a really cool extension method which I think can be beneficial since it covers generics, and reflection (two topics that wasn't explored thoroughly enough in SetFocus IMO).

So, first I'll show the code, then I'll do my best to explain:

        public static string ToHtmlTable<T>(this IEnumerable<T> list,string tableSyle, string headerStyle, string rowStyle, string alternateRowStyle)
        {
            var result = new StringBuilder();
            if (String.IsNullOrEmpty(tableSyle))
            {
                result.Append("<table id=\"" + typeof(T).Name + "Table\">");
            }
            else
            {
                result.Append("<table id=\"" + typeof(T).Name + "Table\" class=\"" + tableSyle + "\">");
            }
 
            var propertyArray = typeof(T).GetProperties();
 
            foreach (var prop in propertyArray)
            {
                if (String.IsNullOrEmpty(headerStyle))
                {
                    result.AppendFormat("<th>{0}</th>", prop.Name);
                }
                else
                {
                    result.AppendFormat("<th class=\"{0}\">{1}</th>",headerStyle, prop.Name);
                }
            }
 
 
            for (int i = 0; i < list.Count(); i++)
            {
                if (!String.IsNullOrEmpty(rowStyle) && !String.IsNullOrEmpty(alternateRowStyle))
                {
                    result.AppendFormat("<tr class=\"{0}\">", i%2==0 ? rowStyle : alternateRowStyle);
                }
 
                else
                {
                    result.AppendFormat("<tr>");
                }
                foreach (var prop in propertyArray)
                {
                    object value = prop.GetValue(list.ElementAt(i), null);
                    result.AppendFormat("<td>{0}</td>", value ?? String.Empty);
                }
                result.AppendLine("</tr>");
            }
 
            result.Append("</table>");
 
            return result.ToString();
        }


Ok, let's start with the parameters:

        public static string ToHtmlTable<T>(this IEnumerable<T> list,string tableSyle, string headerStyle, string rowStyle, string alternateRowStyle)


This will allow us to pass in the CSS class of each piece in the HTML table. The way it's coded is that you can pass in null or empty strings and it'll ignore it. Otherwise, it'll enter that as the class name. IE:

<table class="tableClass">


Also notice that the method is generic, so any collection of any kind will work with this method.

            var result = new StringBuilder();
            if (String.IsNullOrEmpty(tableSyle))
            {
                result.Append("<table id=\"" + typeof(T).Name + "Table\">");
            }
            else
            {
                result.Append("<table id=\"" + typeof(T).Name + "Table\" class=\"" + tableSyle + "\">");
            }


Here we start building up the HTML table. If a CSS class was supplied for the table, then we put that in the table tag, otherwise, we don't put any class name. I gave it an ID based on the name of the type that T represents. This may be useful if you want to apply further CSS, so it's good practice to give every element an ID, but in our example we won't actually make use of it. I just left it there for completeness.

            var propertyArray = typeof(T).GetProperties();


Here's where we reflect over T to get an array of PropertyInfo objects. GetProperties returns a PropertyInfo[] array.

            foreach (var prop in propertyArray)
            {
                if (String.IsNullOrEmpty(headerStyle))
                {
                    result.AppendFormat("<th>{0}</th>", prop.Name);
                }
                else
                {
                    result.AppendFormat("<th class=\"{0}\">{1}</th>",headerStyle, prop.Name);
                }


Next, we want to set up the table headers. The headers of the HTML table will be the actual property name. So say you were passing in a List to this method, and your Car class had properties such as "Year", "Make" etc, then that's what would actually appear as the column headers. That's what the PropertyInfo.Name property represents.

            for (int i = 0; i < list.Count(); i++)
            {
                if (!String.IsNullOrEmpty(rowStyle) && !String.IsNullOrEmpty(alternateRowStyle))
                {
                    result.AppendFormat("<tr class=\"{0}\">", i%2==0 ? rowStyle : alternateRowStyle);
                }
 
                else
                {
                    result.AppendFormat("<tr>");
                }


Here we start enumerating the actual IEnumerable that was passed in. For every element in the collection, we want to add a row to our table. Thefore, we first open the tag. However, if the styles for rows are set (both rowStyle and alternateRowStyle) then we need to apply the appropriate class to the row. We can simply check if i is currently an even number (i % 2 == 0). If it is, then we're on a regular row, if it's odd, then we're on an alternate row. If no style is specified, just do a regular tag.

                foreach (var prop in propertyArray)
                {
                    object value = prop.GetValue(list.ElementAt(i), null);
                    result.AppendFormat("<td>{0}</td>", value ?? String.Empty);
                }
                result.AppendLine("</tr>");
            }


Now, we go back to using our PropertyInfo array. For each item in our collection, we want to enumerate over all of it's properties, and get the value for that property. Therefore, first we call the GetValue method on the current PropertyInfo. The first parameter to GetValue, is the object of whose value you want to get. The second one, is if parameters are neccessary to access that property like an indexer. We won't be dealing with that here so we just pass null.

Then, if value isn't null, we append that to the table, else we append a String.Empty. You'll notice the syntax is value ?? String.Empty. That's actually called the "null coalescing operator" It's basically a shorthand way of saying "If value isn't null, use value, else use String.Empty".

            result.Append("</table>");
 
            return result.ToString();
        }


Finally, we just close up the tag and then the tag. Then, we return the result. Now, let's actually test this!

Create a winforms project and add a button to the form, and a WebBrowser control. Then, create a simple Person class like this:

    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    }


No big deal, simple class with three properties. Then, in the button click, create a new List and add a few Person objects to that list:
        private void button1_Click(object sender, EventArgs e)
        {
            var personList = new List<Person>();
            personList.Add(new Person
            {
                FirstName = "Alex",
                LastName = "Friedman",
                Age = 27
            });
 
            personList.Add(new Person
            {
                FirstName = "Jack",
                LastName = "Bauer",
                Age = 45
            });
 
            personList.Add(new Person
            {
                FirstName = "Cloe",
                LastName = "O'Brien",
                Age = 35
            });
 
            personList.Add(new Person
            {
                FirstName = "John",
                LastName = "Doe",
                Age = 30
            });
 
            string html = @"<style type = ""text/css""> .tableStyle{border: solid 5 green;} 
th.header{ background-color:#FF3300} tr.rowStyle { background-color:#33FFFF; 
border: solid 1 black; } tr.alternate { background-color:#99FF66; 
border: solid 1 black;}</style>";
            html += personList.ToHtmlTable("tableStyle", "header", "rowStyle", "alternate");
            this.webBrowser1.DocumentText = html;
        }


Then, I created an html string with all the different CSS styles to simulate a real life scenario where you'll actually have those classes in your CSS file. Finally, call the ToHtmlTable method, and set the webBrowser's DocumentText to the HTML. This is the result:





FirstNameLastNameAge
AlexFriedman27
JackBauer45
CloeO'Brien35
JohnDoe30


Yuck, those colors are nasty! But you get the idea. The nice thing is, since it's generic, and on IEnumerable, any collection of objects that you have can now be turned into an HTML table by calling this one method. Gotta love generics and reflection.

Sunday, March 15, 2009

.Net Reflection Part 2. Loading Assemblies at runtime.

In my first post about Reflection, I gave a basic demo of what can be done using reflection. How you can access metadata about a class such as properties etc. In this post, I'd like to dig a bit deeper into Reflection and show the true power of Reflection and what can be accomplished.

As you may or may not know, Visual Studio has many great addons that can be found across the web. Basically, Microsoft has an API that developers can code against, and then "plugin" their addons into Visual Studio. How is this accomplished? How does it know how to load the code I wrote into Visual Studio? The basic idea behind this is a simple Plugin System that can be accomplished using Reflection. I'll demonstrate the basic premise here to give you a simple understanding of how this all works. This post will be more of a tutorial kind of deal so follow along with me as I go through the steps and I explain them.

Before we do any code, let me explain the basic idea of what we'll do. We're going to create an Interface that we'll call IPluginInterface which will have one simple get property called "Name". All "plugins" will have to implement this interface. At runtime, we will then look in a specific folder for any dll files that have types that implement this interface. If it does, then we know it's a plugin, and we can load it up into our app. May not make sense now, but bear with me. It'll all make sense once we start coding.

OK, fire up Visual Studio and create a Console Application callaed "AssemblyLoadingDemo". Change the default namespace to: SetFocusDemo.Reflection.Demo. You should now see this:

    1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5 
    6 namespace SetFocusDemo.Reflection.Demo
    7 {
    8     class Program
    9     {
   10         static void Main(string[] args)
   11         {
   12 
   13         }
   14     }
   15 }

OK, for now we won't do anything in this project. Now Click on File -> New -> Project and select "Class Library". Call it "PluginInterface". Get rid of the default Class1.cs, and add a class called "IPluginInterface.cs". Then, add this code to the interface:

namespace SetFocusDemo.Reflection.Contract
{
    /// 
    /// This interface will need to be implemented by any class that wants to be a plugin
    /// in our Demo Plugin project.
    /// 
    public interface IPluginInterface
    {
        string Name { get; }
    }
}

Simple interface, doesn't do much really except it has the Name getter like we talked about. In a real life scenario, you would probably have multiple interfaces with multiple methods and properties, but again this is just a demo, so one is enough. Also, please note that I put this in the "SetFocus.Reflection.Contract" namespace.

OK, now, let's actually create a few "Plugins". Basically they'll be classes that will implement this interface.First, let's create another Project. Click File -> New -> Project and create a Class Library called "Plugin Library". Then, right click on "References" and click "Add Reference". Select the Projects tab on top and click select the "Plugin Interface" assembly. Once that's done, remove the default "Class1.cs" and add a new class called "CustomPlugin1". Then, add this code:

namespace PluginLibrary
{
    using SetFocusDemo.Reflection.Contract;
public class CustomPlugin1 : IPluginInterface
    {
        public string Name
        {
            get { return "Custom Plugin 1"; }
        }
    }
}

Doesn't do all that much, but it implements the IPluginInterface and just returns it's name. Now, add another class to this project, and call it "AnotherPlugin". Then add this code:

namespace PluginLibrary
{
    using SetFocusDemo.Reflection.Contract;
public class AnotherPlugin : IPluginInterface
    {
        public string Name
        {
            get { return "Another Plugin"; }
        }
    }
}

Same thing as before really. Another class that implements the same interface. Now, click on the Build menu and click "Build PluginLibrary". Once that's done, right click on the "Plugin Library" project on the right side in solution explorer and click on "Open Folder in Windows Explorer". Then, go to the Bin -> Debug folder and copy the "PluginLibrary.dll" file. Then, open your MyDocuments folder and paste it in there.

OK, we finally have all the code set up to actually write our Plugin Loader. This is where the Reflection magic will happen. Go back to the first project that we called "AssemlyLoadingDemo". First, add a reference to the "Plugin Interface" project and add the using statement on top: "using SetFocusDemo.Reflection.Contract;" Add a new class and call it "PluginLoader.cs". This class will have one static method that will return an array of all the IPluginInterface objects it found and created. Here's the actual code of the class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SetFocusDemo.Reflection.Contract;
using System.IO;
using System.Reflection;
 
namespace SetFocusDemo.Reflection.Loader
{
    public class PluginLoader
    {
        public static IPluginInterface[] GetPlugins(string directory)
        {
            if (String.IsNullOrEmpty(directory)) { return null; } //sanity check
 
            DirectoryInfo info = new DirectoryInfo(directory);
            if (!info.Exists) { return null; } //make sure directory exists
 
            List<IPluginInterface> plugins = new List<IPluginInterface>();
            foreach (FileInfo file in info.GetFiles("*.dll")) //loop through all dll files in directory
            {
                //using Reflection, load Assembly into memory from disk
                Assembly currentAssembly = Assembly.LoadFile(file.FullName); 
 
                //Type discovery to find the type we're looking for which is IPluginInterface
                foreach (Type type in currentAssembly.GetTypes())
                {
 
                    if(!type.ImplementsInterface(typeof(IPluginInterface)))
                    {
                        continue;
                    }
 
                    //Create instance of class that implements IPluginInterface and cast it to type
                    //IPluginInterface and add it to our list
                    IPluginInterface plugin = (IPluginInterface)Activator.CreateInstance(type);
                    plugins.Add(plugin);
                }
            }
 
            return plugins.ToArray();
        }
    }
}

There's alot of code here, I know and I'll do my best to explain. Before I do that though, two things to note. First, you'll see a using statment on top to System.Reflection. Secondly, you'll see this line of code: type.ImplementsInterface(typeof(IPluginInterface)) but that's an extension method I wrote. (For more on extension methods, see my blog post about them here.) Right click on the project and add a class called "TypeExtensions". Here's the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace SetFocusDemo.Reflection.Loader
{
    public static class TypeExtensions
    {
        public static bool ImplementsInterface(this Type type, Type interfaceType)
        {
            return type.GetInterfaces().Contains(interfaceType);
        }
    }
}

Simple method that checks to see if a given type implements a specific interface.

OK, now we can go back and explain what's going on here.

The GetPlugins method takes a directory name as it's parameter indicating where we want to check for plugins. First we just do some sanity checking to make sure we don't get any Null Reference Exceptions:

     if (String.IsNullOrEmpty(directory)) { return null; } //sanity check
     DirectoryInfo info = new DirectoryInfo(directory);
     if (!info.Exists) { return null; } //make sure directory exists

Now we know our "info" object points to the directory we want to look for Plugins.

List<IPluginInterface> plugins = new List<IPluginInterface>();

Here we just new up a List that will be used to add the plugins found and returned from the method.

foreach (FileInfo file in info.GetFiles("*.dll")) //loop through all dll files in directory
            {
Here we start enumerating all the files in the directory to find dll files. Note: in a real world app, this can be dangerous. You're loading dll's into your app without really knowing that they're safe. In a real world, you'd load them into a seperate app domain, but that's out of the scope of this post.

     //using Reflection, load Assembly into memory from disk
     Assembly currentAssembly = Assembly.LoadFile(file.FullName);

Here we actually load the Assembly from the DLL file found. The Assembly class had many great methods on it which allows you to do all kinds of stuff at runtime. In our case, we'll just be looking through the assembly to find a "Plugin":

 //Type discovery to find the type we're looking for which is IPluginInterface
                foreach (Type type in currentAssembly.GetTypes())
                {
Now, we loop through all the Types found in the Assembly. GetTypes() returns an Array of all the Types found in that assembly. That includes classes, interfaces etc.

      if(!type.ImplementsInterface(typeof(IPluginInterface)))
      {
         continue;
      }

Here we look at the type to see if it implements our interface. The idea here is, if a class wants to be a plugin to our App, it MUST implement our IPluginInterface. If it doesn't it can't be a plugin, in which case we just "continue" and go to the next type found in the Assembly.

            //Create instance of class that implements IPluginInterface and cast it to type
           //IPluginInterface and add it to our list
           IPluginInterface plugin = (IPluginInterface)Activator.CreateInstance(type);
           plugins.Add(plugin);

If we DID find a type that implements our interface, then we actually Create an Instance of that type using Activator.CreateInstance(type). We then cast it to the type of our interface, and add it to our list. Activator.CreateInstance is a really cool method that allows you to dynamically load up objects at runtime.

Finally we clost up and return the List as an array:

return plugins.ToArray();

Ok, we now have all the code to give this a wirl. Go back to your Program.cs and in the main method add this code:

static void Main(string[] args)
        {
            //load plugins from MyDocuments. This is just a demo, in a real scenario, you'd use some
            //specific custom folder
            IPluginInterface[] plugins = PluginLoader.GetPlugins(
                Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
 
            foreach (IPluginInterface plugin in plugins)
            {
                Console.WriteLine("Plugin: \"{0}\" was found and loaded.", plugin.Name);
            }
 
            Console.ReadLine();
        }

Basically, call our static method that loads up the plugins, loop through them and print out the name. Here's the output you should see:

Plugin: "Custom Plugin 1" was found and loaded.

Plugin: "Another Plugin" was found and loaded.

What happened here? Basically, we copied our "Plugins" to our MyDocuments folder. When our PluginLoader went to look for Assemblies, it looked in the MyDocuments folder, and found our PluginLibrary.dll. It then loaded up the assembly and looked through the Types found there. It found "CustomPlugin1" and "AnotherPlugin". Then, it actually created instances of each of those classes and cast them as IPluginInterface. This is key! At design time, we have NO idea what the type we'll be. Any developer coding against our IPluginInterface API can create their own class that implements IPluginInterface. We have no clue what his class will be. What we DO know is that it will be of type IPluginInterface. Therefore, when we create an instance of it using Activator.CreateInstance, and cast it to the only type we know of which is IPluginInterface. Then, we can call the methods on our interface which in our cast is the Property "Name".

This post turned out to be alot longer than I thought. There's alot happening here, so if you have any questions, seriosuly, email me at a.friedman07@gmail.com or post a comment here.

Friday, March 13, 2009

.Net Reflection, hey look I can see myself!

Towards the end of Week 1 in the Master's Program, we touched on Reflection and were shown how they can be used with attributes. Here's a quick review. Let's decorate our Person class we keep using with a Description attribute.

   63     [Description("This represents a Person's basic information.")]
   64     public class Person
   65     {
   66         public string FirstName { get; set; }
   67         public string LastName { get; set; }
   68         public int Age { get; set; }
   69     }

What we were taught that first week was how to get the information from an attribute at runtime. Here's a simple way of doing it. In fact, just to make it a little more interesting, let's actually make this an extension method on object, so that any time an object has a Description attribute, we could simple do this:

   57 string description = myObject.GetDescription();

Here's how we can do it:

   72     public static class ObjectExtensions
   73     {
   74         public static string GetDescription(this object o)
   75         {
   76             Type type = o.GetType();
   77             object[] attributes = type.GetCustomAttributes(typeof(DescriptionAttribute), false);
   78             if (attributes.Length == 0)
   79             {
   80                 return String.Empty; //no Description attribute found
   81             }
   82 
   83             DescriptionAttribute description = (DescriptionAttribute)attributes[0];
   84             return description.Description;
   85         }
   86     }

The Type class is what really gets us started. Every object in the .NET Framework has a method called GetType() which returns a Type object. You can also get the type by using the typeof keyword to get you a speficic type. IE: If you want the "Type" of our Person object, you would do:

   58 Type personType = typeof(Person);

So if you have an object, you can call GetType() however if you don't actually have an object, but you need to get information about a sepcific Type (class), you use the typeof keyword. So in our example, we first get the Type from the object passed in, and then we use the methods on the Type class to retrieve the attributes. This is the tip of the iceberg for Reflection. Reflection is unique in the sense that you're actually examining the type of a specific class at runtime. Generally when dealing with an object, you get the values of a specific object, such as the Person's Name, or a Car's Color etc.. Reflection on the other hand tells us about the class (type) itself.

Getting attributes is just the beginning. You can do alot of really cool things with Reflection, and I'll try to demonstrate a few of them.

Using Reflection, you can get all the members of a class. You can get the Properties, Members, Methods etc. If you remember, during the first project at SetFocus, we had a requirement like this:

Provide a named enumerator called PropertyAndValuesCollection that allows for easy enumeration over a set of string values that provide information about the current Supplier object. The string values returned by the enumerator should take the user over all of the property values of the current Supplier object in the output format of: PropertyName: PropertyValue.
We had to have a method that returned all the Properties and their values of a Supplier object. So, not knowing much about reflection, most of us did something like this:

  182         public  System.Collections.IEnumerable PropertyAndValuesCollection()
  183         {
  184             yield return "ID: " + ID;
  185             yield return "CompanyName: " + CompanyName;
  186             yield return "ContactName: " + ContactName;
  187             yield return "ContactTitle: " + ContactTitle;
  188             yield return "Address: " + Address;
  189             yield return "City: " + City;
  190             yield return "Region: " + Region;
  191             yield return "PostalCode: " + PostalCode;
  192             yield return "Country: " + Country;
  193             yield return "Phone: " + Phone;
  194             yield return "Fax: " + Fax;
  195             yield return "HomePage: " + HomePage;
  196             yield return "Type: " + Type.ToString();
  197         }

This worked, and the TestHarness considered this to be OK. However, hardcoding anything sucks! What if you add/remove properties of this supplier class, now you have to remember to go change this method. Wouldn't it be better if we can just examine the class at runtime and return all the properties? Well, here's how you can do it using Reflection:
  183  public IEnumerable PropertyAndValuesCollection()
  184         {
  185             Type type = this.GetType();
  186             PropertyInfo[] infos = type.GetProperties();
  187             for (int i = 0; i<infos.Length;i++)
  188             {
  189                 yield return String.Format("{0}: {1}", infos[i].Name,
infos[i].GetValue(this, null));
  190             }
  191         }

I tested this with the TestHarness and it does in fact pass. What's happening here is very simple. First we get the Type of this class (Supplier). We could also have done Type type = typeof(Supplier). Same thing, doesn't matter. Then, we call the GetProperties method on the type object that returns an array of PropertyInfo objects. The PropertyInfo class has a property on it called Name which is just that, the name of the actual property. Then, this is where reflection really shines, it has a method called GetValue. This method enables us to actually get the value of an object at runtime!

Here's another demonstration of when this can be useful. Say you want to add a ToXml() method to your class that writes out all the values of your class to an XML string. (Yes, I know there are already classes in the .NET Framework that do this, but even wonder how they do it? :) ) Here's a simple code sample. We'll add this to our Person class:

   72 [Description("This represents a Person's basic information.")]
   73     public class Person
   74     {
   75         public string FirstName { get; set; }
   76         public string LastName { get; set; }
   77         public int Age { get; set; }
   78 
   79         public string ToXml()
   80         {
   81             Type type = this.GetType();
   82             StringBuilder builder = new StringBuilder();
   83             StringWriter stringWriter = new StringWriter(builder);
   84             XmlTextWriter writer = new XmlTextWriter(stringWriter);
   85             writer.WriteStartDocument();
   86             writer.WriteStartElement(type.Name);
   87             foreach (var prop in type.GetProperties())
   88             {
   89                 writer.WriteAttributeString(prop.Name,
prop.GetValue(this, null).ToString());
   90             }
   91             writer.WriteEndElement();
   92             return builder.ToString();
   93         }
   94     }

Now let's say we have a Person object like this:

   25             Person p = new Person
   26             {
   27                 FirstName = "Alex",
   28                 LastName = "Friedman",
   29                 Age = 27
   30             };

Now, let's call our ToXML method:

   32 string xml = p.ToXml();

This would be the result:

   37 <?xml version="1.0" encoding="utf-16"?><Person FirstName="Alex" LastName="Friedman" Age="27" />


Not very pretty, but you get the point!

In future posts, I'll dig deeper into Reflection and show some even more crazy stuff you can do like loading Assemblies at runtime and invoking methods on them.