SingleInstance(Of T) Class for Windows Phone 7

November 20, 2010 | Async

When building applications for a mobile operating system such as Windows Phone 7 (WP7) you might want (at times) to defer the creation of large objects,  specifically when this creation is going to increase memory consumption.

While in the desktop CLR there is the Lazy(Of T) Class, when working on WP7 this class does not exist (at least not at the time of this writing).

I find it a very repetitive task to manually produce a single instance object:

  1. Make it’s constructor private.
  2. Write the code for initialization.
  3. Provide a getter method that returns the one and only instance.

While you can not avoid step 2, it is possible to create a generic class that produces step 1 and step 3. Then, from the class constructor, you can pass the code that creates the object using a Func(TResult) Delegate

SingleInstance(Of T) Class

using System;
using System.Threading;

internal sealed class SingleInstance<T> where T : class
{
    private readonly object  lockObj = new object();
    private readonly Func<T> @delegate;
    private bool isDelegateInvoked;

    private T @value;

    public SingleInstance()
        : this(() => default(T)) { }

    public SingleInstance(Func<T> @delegate)
    {
        this.@delegate = @delegate;
    }

    public T Instance
    {
        get
        {
            if (!this.isDelegateInvoked)
            {
                T temp = this.@delegate();
                Interlocked.CompareExchange<T>(ref this.@value, temp, null);

                bool lockTaken = false;

                try
                {
                    // WP7 does not support the overload with the
                    // Boolean indicating if the lock was taken.
                    Monitor.Enter(this.lockObj); lockTaken = true;

                    this.isDelegateInvoked = true;
                }
                finally
                {
                    if (lockTaken) { Monitor.Exit(this.lockObj); }
                }
            }

            return this.@value;
        }
    }
}

The code inside the “T Instance” public property uses interlocked constructs to produce a single T object. It has been discussed in the book CLR via C#, 3rd Edition, Microsoft Press, page 846.

The SingleInstance(Of T) class has many differences from the  System.Lazy(Of T) class in the desktop CLR.

Keep in mind that the SingleInstance(Of T) class uses a Func(TResult) Delegate. There is a known performance hit when calling delegates compared to direct method calls. (See the Delegates section here).