Object Oriented Programming Patterns for Geeks
A Simple Singleton
The basic idea of the Singleton is to ensure that a class has only one instance and that a mechanism is in place to provide global access to it. In practice this is quite simple:
- You call a static method or property on the class. That member checks to see whether or not its associated object has been instantiated.
- If it hasn’t, then this is the first call. It locks itself, checks again just in case another thread slipped in before the locking action could be completed (double check locking), and then if everything is ok, it instantiates the object. Then it returns the object to the caller.
- If it has already been instantiated, it simply returns to the caller.
Also, to ensure that the class can not be arbitrarily instantiated, you need to make the constructor protected, protected internal or private. This ensures that only the static method/property on the class or an inheritor can instantiate the object.
Essentially this gives every object within your program access to the same instance of your object.
In the code below if you are sharp you may find a 'deliberate mistake' with that thing about double checked locking. Notice that I am not doing the check-lock-check pattern and I am using the 'Interlocked' class's abilities instead. In .NET this is a valid way to do the same thing. However, there are other ways to achieve the same thing although in reality you should try and limit yourself to the method I use, or swap in the locking for the following (of course ensure there is an object instance to lock against):
if ( _Me == null )
lock ( _lockingObject )
if ( _Me == null )
{
SimpleSingleton tmp = new SimpleSingleton();
// Essential due to memory synchronization
// on multi CPU systems...
Thread.MemoryBarrier();
_Me = tmp ;
}
While the above method is just as valid, it is more long winded and slower that the Interlocked methods. It is really down to personal preference.
sealed class SimpleSingleton
{
/// <summary>
/// This holds the actual instance (based on AppDomain context)
/// </summary>
private static SimpleSingleton _Me;
/// <summary>
/// Some basic instance data.
/// </summary>
private string _SomeInstanceData;
/// <summary>
/// Gets or sets some instance data.
/// </summary>
/// <value>Some instance data.</value>
public string SomeInstanceData
{
get { return this._SomeInstanceData; }
set { Interlocked.Exchange<string>
( ref this._SomeInstanceData, value ); }
}
/// <summary>
/// Initializes a new instance of the
/// <see cref="SimpleSingleton"/> class.
/// This is privately invoked
/// </summary>
private SimpleSingleton()
{
this._SomeInstanceData = "Hi!";
}
/// <summary>
/// Gets the singleton.
/// </summary>
/// <value>The singleton.</value>
public static SimpleSingleton Singleton
{
get
{
if( _Me == null )
Interlocked.CompareExchange<SimpleSingleton>
( ref _Me, new SimpleSingleton(),null );
return _Me;
}
}
}
There is a proviso that needs to be mentioned here. You need to remember that in Web Applications, static access is available to the entire applications domain. This means that all active sessions and their threads will have access to the same object. It is important to ensure that when using this pattern that your web application is thread-safe.
Many developers use this form of Singleton to allow global access to cached data that the entire application can access, and while this is a good use for this pattern, ASP.NET does supply as part of it's architecture the use of the Application dictionary. An example of a form of singleton that uses the ASP.NET architecture can be found here.
The next pattern explored is the ThreadSingleton.