myfavoritemovies.us

September 2, 2008

Factory pattern through reflection.

Last week I came across a situation where, I need to implement bunch of classes which perform same task differently when it is called. (Simply put, factory pattern). So I thought, based on GOF it is a simple implementation.

Create a abstract factory class and then create sealed worker class which implement the actual task. Simple enough. In the main program have a switch which checks the incoming parameter and based on the parameter, we create instance of a proper worker class and vola we got the implementation done.

Now the point to remember here is, if we need to add a new worker class, what are all the elements involved? First you need to add a new case statement for the new worker class initation and then add the new worker class itself. Two code changes. Not a big deal. But if you happen to have too many implementation or in other words too many worker implementation then your switch statement could grow larger and larger.

This limiation forced me to think if there is any other way of creating classes on the fly. I talked to one my collegue and he pointed me to one his implementation he is currently using that is using reflection. So here is how it is implemented.

First create the interface you would like the factory workers to implement. Something like the following;

IWorker.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TraditionalFactory
{
public interface IWorker
{
void SayName(string name);
}
}

You can see all we are trying to implement is a ‘SayHello’ method. Following two are two worker implementation of the Factory Interface;

Worker1.cs:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TraditionalFactory
{
public class Worker1:IWorker
{
#region IWorker Members

public void SayName(string name)
{
Console.WriteLine("Name from first worker is {0}", name);
}

#endregion
}
}

Worker2.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TraditionalFactory
{
public class Worker2:IWorker
{
#region IWorker Members

public void SayName(string name)
{
Console.WriteLine("Name from second worker {0}", name);
}

#endregion
}
}

Based on the interface and the worker implementation there is nothing new. The code that make this one work without big switch statement is in the main program.

Program.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace TraditionalFactory
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Which worker to run (Worker1 or Worker2?");
string workerName = Console.ReadLine();
Type workerType = Type.GetType("TraditionalFactory."+workerName);
IWorker worker = (IWorker)Activator.CreateInstance(workerType);
worker.SayName("data passed");
Console.ReadKey();
}
}
}

This factory model implementation compltly depends on the reflection feature of C#. This also depends on the the consumer to this program aware of which worker they need to consume by name or you need to create a dictionary mapping of the user input to worker class mapping of some sort. For this implementation I am assuming the consumer knows which worker to use.

The point of interests are, first creating the type of the class we are going to instantiate. In our class we are going to find the factory interface type of execuing assembly using ‘Type.GetType’ method call. Which looks at the executing assembly or clr to see if it finds matching type. If you look at the code closely, since we already know which worker that we are interested to consume based on ‘workerName’, we look for the namespace + workerName in the GetType. (This is where reflection come into get the type of the class we are trying to consume). Once the type identified, we call in the ‘Activator.CreateInstance’ method to create the instance of the worker class through the interface and then execute the public method from the interface. Thats it, we got ourself Factory pattern implemented.

The benefit of this implementation is that, when you want to add a new worker class, you simply add the worker class, compile it and deliver the exe. No more main program change. One code change and you are done.

The problems I see with the implementation is that, you need agree on how the consumers are going to consume the worker class and make appropriate mapping before hand or make the consure to call in with appropriate worker name explicitly (like the example below).

One for my notes….

Powered by WordPress