The implementation of the singleton pattern is pretty easy. However, despite the simplicity I see often that the pattern is being misused or implemented wrongly.
What I’ve seen so far:
- The implementation is not thread-safe. (coding issue)
- Tight coupling: The business code/logic accesses a static property of a class in order to utilize the singleton instance. (architectural/design issue)
- Scope: Not all are aware of the fact that the singleton instance inside an web application is accessible within all user requests. (architectural/design issue)
- Usage of singleton where it is not needed at all. (architectural/design issue)
- Other bad things I finally managed to forget after excessive drinking. 🙂
Overall, it is a good design pattern but I don’t agree with the recommended way of implementing it. I usually try to follow one of these approaches mentioned below.
1) Lazy<> class
If you are a .NET developer you can make use of the Lazy<> class. The constructor expects a Func<T> function in order to initialize the singleton instance. The implementation below is thread-safe. However, our code which uses this singleton class is still tightly coupled to
public class SingletonExample { private static readonly Lazy<SingletonExample> _instance = new Lazy<SingletonExample>(() => new SingletonExample()); private SingletonExample() { } public static SingletonExample Instance { get { return _instance.Value; } } }
2) Lifetime management through dependency injection
This is definitely my favorite approach. But it requires a dependency injection framework. (I prefer Unity)
Almost every DI framework allows to control the lifetime of objects. The following example shows how to configure Unity in order to have just one instance of a specific class (in this case here “SingletonExample” class).
As you see here, there is no explicit Singleton implementation. The code below sets up a UnityContainer and registers the SingletonExample type with the ContainerControlledLifetimeManager. This lifetime manager ensures that only one instance of SingletonExample class exists within the UnityContainer.
There are many other lifetime managers out there. Therefore it is quite easy to change the behavior if required.
Also unit testing is now much simpler, since any instance of a class which impelments ISingletonExample can be injected through constructor/property injection.
... var container = new UnityContainer(); container.RegisterType<ISingletonExample, SingletonExample>(new ContainerControlledLifetimeManager()); container.RegisterType<IMyLogic, MyLogic>(); var logic1 = container.Resolve<IMyLogic>(); var logic2 = container.Resolve<IMyLogic>(); ... public interface ISingletonExample { } public interface IMyLogic { } public class SingletonExample : ISingletonExample { } public class MyLogic : IMyLogic { private readonly ISingletonExample _singleton; public MyLogic(ISingletonExample singleton) { this._singleton = singleton; } }