C# Singleton

Wiki Text
Section body

Singleton to kreacyjny wzorzec projektowy, który pozwala definiować klasy posiadające tylko jedną, globalnie dostępną instancję.

Section title

Budowa i działanie

Section image
Obraz
Singleton - instance: Singleton - Singleton() +getInstance():Singleton
Section title

Zastosowanie

Section body

Ze względu na swoją prostotę Singleton jest dosyć popularnym wzorcem, wykorzystywanym najczęściej  do tworzenia zmiennych globalnych w językach, które ich nie obsługują.

 

Section title

Prosty Singleton

Section body
sealed class Singleton {
    private static readonly Singleton instance = new Singleton();
    private Singleton(){}
    static Singleton(){}
    public static Singleton Instance => instance;
}

Powyższy przykład zawiera najważniejsze cechy singletonów:

  • prywatny konstruktor - uniemożliwia bezpośrednie tworzenie instancji klasy oraz dziedziczenie
  • modyfikator sealed - w tym przypadku nie ma on zastosowania do klasy singletona lecz uniemożliwia dziedziczenie przy pomocy typów zagnieżdżonych
  • prywatna, statyczna i tylko do odczytu składowa instance będąca referencją do instancji singletona
Section title

Leniwy Singleton

Section body
sealed class Singleton
{
        private static readonly object syncLock = new object();
        private static Singleton instance;
        private Singleton() { }
        static Singleton() { }
        public static Singleton Instance { 
            get
            {
                if (instance == null)
                {
                    lock (syncLock)
                    {
                        if (instance == null)
                        {
                            instance = new Singleton();
                        }
                    }
                }
                return instance;
            }    
        }
}
sealed class Singleton
{
     private static readonly Lazy<Singleton> instance = new Lazy<Singleton>(() => new Singleton());
     public static Singleton Instance => instance.Value;
     private Singleton() { }
}

 

Section title

Fabryka singletonów

Section body
 public class Singleton<T> where T : class, new()
    {
        private static readonly object syncLock = new object();
        private static T instance;

        protected Singleton(){}

        public static T Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncLock)
                    {
                        if (instance == null)
                        {
                            instance = new T();
                        }
                    }
                }
                return instance;
            }
        }
    }

 

Section title

Singleton jako zabezpieczanie

Section body

Nie traktujmy singletona jako zabezpieczenie 

Singleton s1 = Singleton.Instance;
var s2 = s1.GetType().GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(s1, null);