Using Factory Method Pattern with System.Activator


Over the time I spent developing, I have used Factory Method Pattern numerous times to create my objects. It provides a layer of abstraction by using an interface (or abstract base class) to hide away your concrete implementations. At runtime, we don’t care about the concrete objects that is being returned because we should always strive to program to an interface, not an implementation.

This pattern is not without it’s demerits. I’ve seen crazy implementations where the use of a string-based key is used to identify what objects to instantiate, followed by a massive switch (C#) or Select Case (VB.NET) to determine which concrete class to instantiate. This is ugly, and you have to extend the switch statement when you add a new class. Of course you could use a Dictionary to store the keys, or store them in Configuration but you will need write plumbing code to load them at runtime. With string-based keys, it’s very error prone and somewhat bothersome to troubleshoot.

Alternatively, there are also Dependency Injection frameworks out there that can alleviate such problems, like Castle Windsor, Spring.NET, just to name a few. However, you need to spend time to get up to speed with the API, and if you only want to deal with what the .NET framework provides you, here’s what I have done previously. I used a enum class in substitution of a string key, and the System.Activator class to create my objects dynamically.

For this example, I’m creating a factory method to load WinForms UserControls based on a key, which is an enum. First define an interface called IControl. You should put properties, events and methods that are common. You could also use an abstract base class if you want to.

public delegate void ScreenChangeEVentHandler(Screens screen);

public interface IControl
{
    bool HandleKeyStroke(Keys key);
    event ScreenChangeEVentHandler ScreenChangeEvent;
}

Next assuming you currently have two UserControls, called MainMenu.cs and ProductDetails.cs, you will need to create an enum class to contain them. Important, you need to make sure the enum has the same name as your UserControl names, like so…

public enum Screens
{
    MainMenu = 0,
    ProductDetails= 1
}

Last of all, we have our factory method, which takes in our enum as an input parameter. First we need to specify the type using full qualified name, <namespace>.<classname> format. We can get the <namespace> using System.Reflection.AssemblyName and the <classname> is just simply the .ToString() of the enum key. Once we have done that, we use System.Activator to create our object for us, and cast it our interface.

public static class ControlFactory
{
    public static IControl CreateControl(Screens screen)
    {
        string assemblyName = Assembly.GetExecutingAssembly().GetName().Name;
        IControl control = Activator.CreateInstance(null, string.Format("{0}.{1}", assemblyName, screen)).Unwrap() as IControl;
        if (control == null)
        {
            // or you can throw an Exception here.
            control = new NullControl(string.Format("Error creating screen of type {0}, screen));
        }
        return control;
    }
}

I’m using Activator.CreateInstance method, and there are 12 overloads to choose from. When I get an error instantiating my object, I handle it by creating a NullControl (a container that displays my error message) , which follows the Null Object pattern. If your rather throw an Exception instead, that’s perfectly fine, just remember to handle it appropriately.

As your library of UserControls grows, you only need to extend your enum class. As enum is strongly typed, you will not be able to make typo errors like with a string based key. Of course, the only downside is that you have to ensure that your enum name is exactly the same as your class name, but that’s a small overhead compared to maintaining a long list of string based key. As with all technical solutions, there are always tradeoffs and it goes down to just a matter of “the lesser of two evils”. This approach is more elegant (less code) and easier to troubleshoot.

Another cool thing with this approach of using an enum key is that you can define meta-data using Attributes. This provides for a richer contextual model which we can utilize to do interesting stuff, which I will leave for my next post. Til then happy coding.

Share this post:
Advertisements

One Response to “Using Factory Method Pattern with System.Activator”

  1. Fun with Attribute Programming « Code Blitz Says:

    […] Using Factory Method Pattern with System.Activator […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: