Disposing of the Singleton instance when it is no longer needed
Most examples show instantiating and holding a
LazySingleton object until the owning application has terminated, even if that object is no longer needed by the application. A solution to this is to implement
IDisposable and set the object instance to null as follows:
The above code disposes of the instance prior to application termination but only if consumers call
Dispose() on the object after every use. Since there is no guarantee that this will happen or a way to force it, there is also no guarantee that the instance will ever be disposed. But if this class is being used internally then it's easier to ensure that the
Dispose() method is being called after each use. An example follows:
Please note that this example is not thread-safe.
Lazy, thread safe singleton (for .NET 3.5 or older, alternate implementation)
Because in .NET 3.5 and older you don't have
Lazy<T> class you use the following pattern:
This is inspired from Jon Skeet's blog post.
Nested class is nested and private the instantiation of the singleton instance will not be triggered by accessing other members of the
Sigleton class (such as a public readonly property, for example).
Lazy, thread-safe Singleton (using Double Checked Locking)
This thread-safe version of a singleton was necessary in the early versions of .NET where
static initialization was not guaranteed to be thread-safe. In more modern versions of the framework a statically initialized singleton is usually preferred because it is very easy to make implementation mistakes in the following pattern.
Notice that the
if (instance == null) check is done twice: once before the lock is acquired, and once afterwards. This implementation would still be thread-safe even without the first null check. However, that would mean that a lock would be acquired every time the instance is requested, and that would cause performance to suffer. The first null check is added so that the lock is not acquired unless it's necessary. The second null check makes sure that only the first thread to acquire the lock then creates the instance. The other threads will find the instance to be populated and skip ahead.
Lazy, thread-safe Singleton (using Lazy
.Net 4.0 type Lazy guarantees thread-safe object initialization, so this type could be used to make Singletons.
Lazy<T> will make sure that the object is only instantiated when it is used somewhere in the calling code.
A simple usage will be like:
Statically Initialized Singleton
This implementation is thread-safe because in this case
instance object is initialized in the static constructor. The CLR already ensures that all static constructors are executed thread-safe.
instance is not a thread-safe operation, therefore the
readonly attribute guarantees immutability after initialization.