Singleton to wzorzec często przydający się w większych aplikacjach np w odniesieniu do połączenia z bazą danych czy innym źródłem danych.
Jak prawidłowo zaimplementować wzorzec singleton.

Kod dla aplikacji jednowątkowych:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public sealed class Singleton
{
   private static Singleton instance;

   private Singleton() {}

   public static Singleton Instance
   {
      get
      {
         if (instance == null)
         {
            instance = new Singleton();
         }
         return instance;
      }
   }
}


Prosty singleton składa się z:
– prywatnego konstruktora, wyklucza tworzenie instancji poza obiektem.
– prywatnego statycznego pola reprezentującego jedyną instancję singletonu.
– metody dostępowej zwracającej instancję singletona.

Metoda dostępowa zazwyczaj sprawdza czy pole instancji nie jest puste (null) i jeżeli jest to tworzy obiekt. Oznacza to oczywiście, że obiekt jest tworzony przy pierwszej próbie pobrania. Jest to forma opóźnionej/leniwej inicjacji (Lazy Initialization)

Sama klasa jest oznaczona jako sealed, czyli nie można z niej dziedziczyć. Nie chcemy, by ktoś stworzył klasę potomną, która będzie pozwalała na utworzenie wielu instancji.

Poprawna implementacja dla aplikacji wielowątkowej:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System;

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance
   {
      get
      {
         if (instance == null)
         {
            lock (syncRoot)
            {
               if (instance == null)
                  instance = new Singleton();
            }
         }

         return instance;
      }
   }
}

mały przykład w wpf: Singleton C# (1197)
źródło: http://msdn.microsoft.com/en-us/library/ms998558.aspx