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:
public class LazySingleton : IDisposable
{
private static volatile Lazy<LazySingleton> _instance;
private static volatile int _instanceCount = 0;
private bool _alreadyDisposed = false;
public static LazySingleton Instance
{
get
{
if (_instance == null)
_instance = new Lazy<LazySingleton>(() => new LazySingleton());
_instanceCount++;
return _instance.Value;
}
}
private LazySingleton() { }
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
if (--_instanceCount == 0) // No more references to this object.
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (_alreadyDisposed) return;
if (disposing)
{
_instance = null; // Allow GC to dispose of this instance.
// Free any other managed objects here.
}
// Free any unmanaged objects here.
_alreadyDisposed = true;
}
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:
public class Program
{
public static void Main()
{
using (var instance = LazySingleton.Instance)
{
// Do work with instance
}
}
}
Please note that this example is not thread-safe.