Singleton an anti-pattern?
The happy side of using singletons
Log.Trace("Putting a trace logging");
Drawbacks
Unit-testing
Threads
1. public class MySingleton
2. {
3. public static MySingleton GetInstance
4. {
5. get
6. {
7. if (instance == null)
8. {
9. m_instance = new MySingleton();
10. }
11. return m_instance;
12. }
13. }
14.
15. private MySingleton () {}
16.
17. private static MySingleton m_instance;
18. }
The way the instance of MySingleton is created, is referred as lazy initialisation. This means, the instance is created at exact the moment the instance is needed the first time. What if two threads try to access the GetInstance property at the beginning of executing of the program. In this case, m_instance is null. When both threads check on line 7 if instance is null and if they conclude it is indeed null, they both create a new instance of the class.
A way to prevent this is by adding a semaphore and lock it when you get before the check if instance is null. This would be something like this:
1. public class MySingleton
2. {
3. public static MySingleton GetInstance
4. {
5. get
6. {
7. lock(myLock)
8. {
9. if (instance == null)
10. {
11. m_instance = new MySingleton();
12. }
13. }
14. return m_instance;
15. }
16. }
17.
18. private MySingleton () {}
19.
20. private static MySingleton m_instance;
21. private static object myLock = new Object();
22. }
Conclusion
You should use the singleton pattern wisely. In some ways it is indeed an anti-pattern, but for example when using a logging class it can be quite handy. Also be very careful when using singletons within unit-tests!