8 Stimmen

Verwendung eines Singletons anstelle einer globalen statischen Instanz

Ich stieß heute auf ein Problem und ein Freund empfahl mir, eine globale statische Instanz oder eleganter ein Singleton-Muster zu verwenden. Ich verbrachte ein paar Stunden lesen über Singletons, aber ein paar Dinge noch entkommen mir.

Hintergrund: Was Im versuchen zu erreichen ist die Erstellung einer Instanz einer API und verwenden diese eine Instanz in allen meinen Klassen (im Gegensatz zu eine neue Verbindung, etc.).

Es scheint etwa 100 Möglichkeiten zu geben, ein Singleton zu erstellen, aber mit etwas Hilfe von Yoda Ich habe einige fadensichere Beispiele gefunden. also den folgenden Code gegeben:

public sealed class Singleton
{
     public static Singleton Instance { get; private set; }

     private Singleton()
     {
        APIClass api = new APIClass();  //Can this be done?
     }

     static Singleton() { Instance = new Singleton(); }
}

Wie/wo würden Sie diese neue Klasse instanziieren und wie sollte sie von einer separaten Klasse aufgerufen werden?

EDIT: Mir ist klar, dass die Singleton-Klasse mit etwas aufgerufen werden kann wie

Singleton obj1 = Singleton.Instance();

aber wäre ich in der Lage, auf die Methoden innerhalb der APIs-Klasse (z. B. obj1.Start) zuzugreifen? (nicht dass ich das müsste, ich frage nur)

EDIT #2: Ich könnte ein bisschen voreilig bei der Überprüfung der Antwort gewesen sein, aber ich habe eine kleine Sache, die immer noch Probleme verursacht mich. Die API startet einwandfrei, leider bin ich in der Lage, zwei Instanzen zu starten?

Neuer Code

public sealed class SingletonAPI
{
 public static SingletonAPI Instance { get; private set; }

 private SingletonAPI() {}

 static SingletonAPI() { Instance = new SingletonAPI(); }     

 // API method:
 public void Start() { API myAPI = new API();}
 }

aber wenn ich versuche, so etwas zu tun...

SingletonAPI api = SingletonAPI.Instance;
api.Start();
SingletonAPI api2 = SingletonAPI.Instance;  // This was just for testing.
api2.Start();

Ich erhalte die Fehlermeldung, dass ich nicht mehr als eine Instanz starten kann.

10voto

Igby Largeman Punkte 16135

Warum nicht einfach eine öffentliche APIClass-Eigenschaft zu Ihrem Singleton hinzufügen?

public sealed class Singleton
{
     public static Singleton Instance { get; private set; }

     private APIClass _APIClass; 

     private Singleton()
     {
        _APIClass = new APIClass();  
     }

     public APIClass API { get { return _APIClass; } }

     static Singleton() { Instance = new Singleton(); }     
}

Dann sieht Ihre aufrufende Seite so aus:

Singleton.Instance.API.DoSomething();

Oder wenn Sie der Autor der API-Klasse sind, könnten Sie sie selbst zu einem Singleton machen, anstatt sie in ein Singleton zu verpacken:

public sealed class SingletonAPI
{
     public static SingletonAPI Instance { get; private set; }

     private SingletonAPI() {}

     static SingletonAPI() { Instance = new SingletonAPI(); }     

     // API method:
     public void DoSomething() { Console.WriteLine("hi"); }
}

API-Aufruf:

SingletonAPI.Instance.DoSomething();

5voto

James Westgate Punkte 10931

Hier ist die offizieller Ansatz von Microsoft .

Das Schöne am Singleton ist, dass Sie es überall in Ihrem Code verwenden und darauf zugreifen können, ohne eine Instanz der Klasse erstellen zu müssen. Das ist ja auch seine Daseinsberechtigung, eine einzelne Instanz einer Klasse z.B.

Singleton.Instance.MyValue y Singleton.Instance.DoSomething();

3voto

Reed Copsey Punkte 536986

Sie würden die Klasse nicht instanziieren - das Muster, das Sie verwenden, instanziiert sich im Grunde selbst, wenn es zum ersten Mal verwendet wird. Der Vorteil der von Ihnen verwendeten Methode ist, dass sie thread-sicher ist (sie wird nur einmal instanziiert, egal wie viele Threads versuchen, auf sie zuzugreifen), träge (sie wird erst instanziiert, wenn Sie versuchen, auf die Singleton-Klasse zuzugreifen) und einfach in der Implementierung.

Alles, was Sie tun müssen, um dies zu nutzen, ist zu tun:

 Singleton.Instance.MyMethodOnSingleton();

Oder, alternativ:

 Singleton myInstance = Singleton.Instance; // Will always be the same instance...
 myInstance.DoSomething();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X