Welcome to

Magenic Technologies Community Blog

Sign in | Join | Help

Outsourcing to Sleestak

Technical Blog on ASP.NET AJAX, WCF, WPF, and any other shiny tinsel that captures a developer's short attention span, with hands on information about getting the most productivity out of your sleestak workforce.

A Lazier Singleton with .NET 4.0

I will ignore for the moment the common jeremiads against the Singleton pattern and the reports made by some latter-day design pattern nihilists that the Singleton is dead.   I do not mean to imply that they are wrong – it’s just that it galls me that the Singleton pattern should be the object of such scorn and ridicule when the Flyweight is allowed to go along its merry way.

Besides which, the Singleton and the Facade are the only patterns I can write from memory and without a lot of research, so I love ‘em.

The best source for design patterns in C# is probably Judith Bishop’s C# 3.0 Design Patterns published by O’Reilly Press, which provides C# versions of all 23 patterns from the Gang of Four’s Elements of Reusable Object-Oriented Software.  The elegant implementation of the Singleton pattern she recommends looks like this:

public sealed class Singleton {
   // Private Constructor
   Singleton( ) { }

   // Private object instantiated with private constructor
   static readonly Singleton instance = new Singleton( );

   // Public static property to get the object
   public static Singleton Instance {
          get { return instance;}
       }
}

 

There is a problem with this, however.  Because of the way classes with static methods work in C# (or in this case, a static property), type instantiation of the private Singleton field instance happens at an unexpected point.  For an interesting if somewhat dense read on the effect of the beforeFieldInit flag, go here.

I will simply demonstrate the problem by adding some tracking code to Judith Bishop’s recommended implementation:

    public sealed class Singleton
    {
        private static readonly Singleton instance = new Singleton();
        private Singleton()
        {
            // no default constructor
            Console.WriteLine(" >> singleton initialized");
        }

        public static Singleton Instance
        {
            get
            {
                Console.WriteLine("before singleton retrieval");
                return instance;

            }
        }
    }

I will retrieve an instance of this Singleton class from a console application like so:

    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("Calling Singleton instance");
            var s = Singleton.Instance;
            Console.WriteLine("Finished calling Singleton instance");
            Console.ReadLine();
        }
    }
When will the private type be initialized? When will the private constructor be called?  In what order do you think the Console.WriteLines will be invoked?

Ideally the static members of this class would be initialized only when we needed them, and the output would be:

  1. Calling Singleton instance
  2. before singleton retrieval
  3. >> singleton initialized
  4. Finished calling Singleton instance

In actuality, however, this is the result:

singlton_results_1

This is not so bad, you may be thinking.  If our singleton is a large object this creates some additional strain to the system – but as long as the Singleton instance gets used fairly soon after it is instantiated it’s no big deal.

However, what if I come in after you have coded the singleton and decide to add another static method to your class -- not understanding the intricate details of beforeFieldInit – like this:

        public static void Test()
        {
            Console.WriteLine("testing singleton");
        }

and rewrote the calling code like this:

            Console.WriteLine("Calling Singleton test method");
            Singleton.Test();
            Console.WriteLine("Calling Singleton instance");
            var s = Singleton.Instance;
            Console.WriteLine("Finished calling Singleton instance");
            Console.ReadLine();

It may not be immediately obvious but I have seriously messed up your code.  Here is the output:

 

singlton_results_2

Even if we never retrieve the Singleton instance, it will still be initialized when any other static method on our type is called – this is commonly known as a language runtime bummer.

.NET 4.0 introduces a new generic type called Lazy which helps us out of this dilemma.  Lazy is a wrapper class that facilitates thread safe, lazy instantiation of objects.  We can use it to create a new Singleton implementation that replaces the private static Singleton instance with a private static Lazy<Singleton>  instance.  The Instance property will also require a small rewrite to pull our Singleton out of the Lazy wrapper.

The full implementation of the lazy version of the singleton looks like this:

    public sealed class LazySingleton
    {
        // Private object with lazy instantiation
        private static readonly Lazy<LazySingleton> instance = 
            new Lazy<LazySingleton>(
                delegate { 
                    return new LazySingleton(); 
                }
                //thread safety first
                ,LazyExecutionMode.EnsureSingleThreadSafeExecution);

        private LazySingleton()
        {
           // no public default constructor
        }

        // static instance property
        public static LazySingleton Instance
        {
            get{ return instance.Value; }
        }
    }

Some things of note:

1. I pass a delegate as the first parameter to the Lazy constructor. There is a no parameter constructor for the generic Lazy<T> class, but it requires that type T have a public default constructor – which I obviously do not want to provide.  The delegate parameter allows me to indicate that I want to use a different constructor – in order to pass a constructor parameter to Type T, for instance, or to invoke a private constructor, in this case – than the default. 

2. The second parameter, also optional, tells the Lazy instance that I want the lazy instantiation of type T to be thread safe.

3. I retrieve the wrapped type T by asking for the Lazy type’s Value property.

Now it’s time for a contest. I add some Console.WriteLine statements as in the original and I append the malicious static Test() method as in the original.  I rewrite my Console app code to call my original Singleton code and then the new and improved -- .NET 4.0 enhanced -- Lazy Singleton code:

    Console.WriteLine("Calling Singleton test method");
    Singleton.Test();
    Console.WriteLine("Calling Singleton instance");
    var s = Singleton.Instance;
    Console.WriteLine("Finished calling Singleton instance");
    Console.WriteLine();

    Console.WriteLine("Calling Lazy Singleton test method");
    LazySingleton.Test();
    Console.WriteLine("Calling Lazy Singleton instance");
    var lazyS = LazySingleton.Instance;
    Console.WriteLine("Finished calling Lazy Singleton instance");
    Console.ReadLine();

and get the following, very pleasing, results:

singlton_results_3

Now that’s lazy!

Published Thursday, October 01, 2009 9:15 PM by jamesa

Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# I have an iphone but no iphone plan. How can I get Safari & Facebook as well as my other applications to work? @ Sunday, October 25, 2009 9:54 AM

Can u hack into it and play say, super nintendo games or game boy games? How good would the controls be? Are there any cool applications for it if the iphone is hacked into?

________________

[url=http://www.youtube.com/watch?v=aBoMmqEIsGk]unlock iphone 3g[/url]

daupt

# What is the difference between ipod touch and iphone? @ Friday, November 20, 2009 7:00 PM

There are some display images showing on my iphone contact listthat I do not want to be displayed.

________________

[url=http://unlockiphone22.com/]unlock iphone[/url]

daupt

# What do i need to start trading forex in kenya? @ Monday, January 04, 2010 2:03 PM

Apart from having a good strategy and money for initial setup, what do i need to have before i could set up an online company in Singapore and sell forex trading alerts to customers? Any licences? Qualifications? Cheers!

[url=http://forexrobot-review.info]best forex software[/url]

daupt

# What are the Best Forex Trading Platforms? @ Monday, January 04, 2010 2:45 PM

Forex Traders promise high monthly returns and "stop-loss" provisions which suggest that you would never lose all of your money. On the other hand they talk about leverage which suggest that they will always have more to invest than they actually have and therefore all losses will be recovered. I have never heard of high returns and no risk, but this is what the so-called Forex traders are advocating. Is this some kind of scam?

[url=http://forexrobot-review.info]best forex software[/url]

daupt

# viagra @ Thursday, February 25, 2010 6:26 AM

zZDuldUQ  <a href="http://ztlacz.com/ ">nrgETFGr</a>

viagra

# Buy Valium @ Wednesday, March 03, 2010 10:08 AM

Fnlmjdv <a href="http://samuelrutledge.com/valium.html ">Buy Valium</a>

Buy Valium

# Ativan @ Tuesday, March 09, 2010 7:35 AM

FwlxwAEf <a href="http://taksimoldcity.com/ativan.html ">Ativan</a>

Ativan

# Cheap Valium @ Wednesday, March 10, 2010 11:06 PM

lqDdURDJ <a href="http://papptimi.com/valium.html ">Cheap Valium</a>

Cheap Valium

Leave a Comment

(required) 
required 
(required) 
Powered by Community Server, by Telligent Systems