| Author: Noshirwan Sheriyarji 02 Jan 2005 | Member Level: Bronze Points : 0 |
Please publish more such on the other different patterns too but more importantly keep it as simple as this. Thanks, Nosh
|
| Author: Murray E. Watt 04 Jan 2005 | Member Level: Bronze Points : 0 |
A CSharp Singleton Class
Summary
The current singleton sample posted to this form is not as clean as it could be and has a bug. This article presents a cleaner implementation of the singleton pattern and addresses the finalization problem.
Introduction
The singleton pattern is used when you want to have exactly one instance of an object, such a print spooler or a logging facility. It is a clean way of sharing global data such as application settings in an object oriented fashion.
A singleton requires three parts:
• A member to store a reference to the single instance of the object • A private version of the constructor, so that it cannot be created more than once (by making sure the object can only create itself). • A static member by which other objects can get a reference to the singleton
The following in the minimum implementation of the singleton class:
class Singleton { // Singletons have a static member //that points to the one instance
private static Singleton _instance;
// Singletons have a private constructor // This makes sure that the single instance // is only created from with in the Instance accessor.
private Singleton() {}
// The Instance propety will create // the Singleton if it does not exist
internal static Singleton Instance { get { if (_instance == null) { _instance = new Singleton(); }
return _instance; } } }
Since this implementation of a singleton has a referrence to itself, its memeory will not be released until the application ends or the appDomain where the singleton lives is released. If you want to release the memory earlier, we can add a method to null out the sigletons reference to itself. This introduces a potential for bugs which we address later in this article.
To enble the memory to be released earily we can add the following method.
internal static void Release() { _instance = null; }
“Releasing” the singleton does not stop any objects that still retain references to the singleton from continuing to use it. Also there isn’t anything keeping the application from recreating the singleton. There is a benefit to the second point. The application to reduce the memory load when the singleton is not needed; however, when combined with the first point you can end up with two active copies of the singleton.
The solution is to add a flag that lets one know if the instance has been released.
private static bool _isReleased;
The Release method becomes
internal static void Release() { _instance = null; _isReleased = true; }
Then we add the following validation to the properties and methods
if (_isReleased == true) { throw(new Exception("message")); }
The new version of the singleton now looks like this:
#region Using directives
using System;
#endregion
namespace Singleton_Project { class Singleton { // Singletons have a static member // that points to the one instance
private static Singleton _instance; // auto-initialized to null private static bool _isReleased; // auto-initialized to false
// Singletons have a private constructor // This makes sure that the single instance // is only created from with in the Instance accessor.
private Singleton() { }
// The Instance propety will create // the Singleton if it does not exist
internal static Singleton Instance { get { if (_isReleased == true) { throw(new Exception("An attempt has ...")); }
if (_instance == null) { _instance = new Singleton(); }
return _instance; } }
internal static void Release() { if (_isReleased == true) { throw(new Exception("An attempt has ...")); }
_instance = null; _isReleased = true; } }
class Program { static void Main(string[] args) { Singleton reference1ToSingleton = Singleton.Instance; Singleton reference2ToSingleton = Singleton.Instance;
if (reference1ToSingleton == null) { Console.WriteLine("Object not created"); } else { Console.WriteLine("Object created"); }
if (reference1ToSingleton.Equals(reference2ToSingleton) { Console.WriteLine("Both references are to the same object."); } else { Console.WriteLine("The two references are to differenct objects."); } } } }
The output of this program is:
Object created Both references are to the same object.
|
| Author: Murali Krishna Kunapareddy 20 Sep 2005 | Member Level: Bronze Points : 0 |
This sample could be simpler and there is a bug by Murray E. Watt is really great and helped me a lot. In fact, this is betterthan the main.
Thanks once again
Murali Krishna
|
| Author: Nanda 17 Jan 2006 | Member Level: Bronze Points : 0 |
Murrya, awesome sample. Thought we can make it thread safe
internal static Singleton Instance { get { if (_instance == null) { { lock(_instance) { _instance = new Singleton(); } } return _instance; } }
Nice posting in http://www.yoda.arachsys.com/csharp/singleton.html
|