Thursday, November 6, 2008

C# Refactoring with Design Patterns, Singleton

Design patterns have been around for a very long time. As a matter of fact, I found an MSDN article dating back to 2001, mentioning the Singleton, Strategy, Decorator, Composite and State design patterns.

Why don’t we start looking into refactoring with the Singleton design pattern. As you probably know, the Singleton pattern is about offering a single, global point of access to a class, that has only one instance.

One thing I usually do for every application that I work on, is to create a configuration class, that retrieves all of the .config settings, and in some cases, also retrieves configuration settings for the application from a back-end SQL database.

Up until learning about Singletons, I passed the configuration class on to other classes that needed it. Instead, the Singleton design pattern offers a much more elegant approach. Let’s look at my configuration example, without using the Singleton pattern:

public class Config
{
public Config()
{
ConfigSetting1 =
ConfigurationManager.AppSettings[“Setting1”];
}

public string ConfigSetting1 { get; private set; };
}
Now, this is pretty straightforward. When you instantiate the Config class, you’ll get access to the properties that got fetched for you, from the .config file, and/or from other sources. Then I would normally pass my config instance along to the constructor of other classes and so forth. This can be completely avoided with the Singleton design pattern. The idea is, that since my Config class will only exist once in memory, I can simply let my other worker classes access the static singleton config class directly.

Here is the basic approach to create a singleton class in C#:
public sealed class Config
{
// Static constructer.
static Config()
{
}

// This will trigger the private constructor of this class.
private static readonly Config _Config = new Config();
    // On first access, the static constructor will fire, in
// turn triggering the private constructor.
public static Config Instance
{
get { return _Config; }
}

// Prevents a default instance of the Config class from being created.
private Config()
{
// Do your work here...
}
}
The beauty of this approach is that it is thread-safe, something that is extremely important for this design pattern. For a much more detailed explanation of this, along with alternate approaches, I urge you to have a look at this very good article by Jon Skeet:

Implementing the Singleton Patterin in C#
http://www.yoda.arachsys.com/csharp/singleton.html

No comments: