Sie Nutzung des singleton-statt eine Globale, statische Instanz
Ich lief in heute ein problem und ein Freund empfohlen, ich benutze eine Globale, statische Instanz oder mehr aus, ein singleton-Muster. Ich verbrachte ein paar Stunden Lesen, über singletons, aber ein paar Dinge, die noch mir zu entkommen.
Hintergrund:
Was ich versuche zu erreichen, ist das erstellen einer Instanz eines API und verwenden Sie dieses Beispiel, in all meinen Klassen (im Gegensatz zu der Herstellung einer neuen Verbindung, etc).
Scheint es über 100 Möglichkeiten, das erstellen einer singleton-aber mit etwas Hilfe von yoda fand ich einige thread-sichere Beispiele. ..also da den folgenden code:
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 instanziieren die diese neue Klasse und wie sollte es genannt werden, die aus einer separaten Klasse?
BEARBEITEN:
Ich weiß, das Singleton-Klasse aufgerufen werden kann, mit so etwas wie
Singleton obj1 = Singleton.Instance();
aber ich wäre in der Lage, um Zugriff auf die Methoden der APIs-Klasse (dh. obj1.Start)? (nicht, dass ich brauche, um einfach Fragen)
EDIT #2: ich hätte vielleicht ein bisschen voreilig bei der überprüfung der Antwort, aber ich habe eine kleine Sache, die ist immer noch verursacht mir Probleme. Die API bringt nur in Ordnung, leider Im können, starten Sie zwei Instanzen?
Neuen 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();
Bekomme ich eine Fehlermeldung, dass ich nicht starten kann, mehr als eine Instanz.
- Sollten Sie einen privaten Konstruktor, als auch, um zu verhindern, dass eine andere Klasse instanziiert eine Kopie Ihrer Singleton.
- Vielen Dank, ich verpasst, dass.
- Sie werden nicht in der Lage, um Methoden aufzurufen, die auf die api-Klasse, denn es ist nicht ausgesetzt.
- In der Tat können Sie eine Instanz APIClass Objekt innerhalb der private Singleton-Konstruktor. Da der private Konstruktor wird nur einmal aufgerufen, aus dem statischen Konstruktor, AFAIK sieht alles gut aus. Sie erklärt die APIClass wie eine lokale variable, so daß der Spielraum, ist nur innerhalb des privaten Konstruktor. Müssen Sie deklarieren es als privates Mitglied zumindest, wenn Sie es verwenden möchten, darüber hinaus.
- Auf einer seitlichen Anmerkung, wenn Sie bereits über eine API-Klasse kapselt die vollständige API, können Sie immer instanziieren der APIClass als statisches Mitglied einer Klasse, sondern als Zusammenfassung in eigenen Singleton.
- Farstucker, in Bezug auf Ihre Edit #2 Erstens glaube ich, Sie verstehen, aber in deinem Beispiel-api und api2 beziehen sich auf genau das gleiche Objekt - das ist das singleton-bei der Arbeit. Zweitens, werden Sie nicht instanziieren, Ihre API in eine öffentliche Methode. Instanziieren Sie in den privaten Konstruktor die singleton. So wird es nur einmal instanziiert. (Das ist genau das, was ich zeigte in meiner Antwort. Ich bin mir nicht sicher, vielleicht sah Sie meine Antwort, nachdem Sie schrieb Edit #2)
- nochmals vielen Dank für die Geduld mit mir. Die Instanziierung im Konstruktor das problem gelöst.
- Viel Glück! Wenn Sie irgendwelche Probleme mit multithreading, der Artikel im MSDN-Artikel unten erwähnt hat, etwas mehr Hilfe.
- Copsey Der Klasse versiegelt ist, muss ich noch ein Konstruktor?
- Ja. Versiegelt nur verhindert, dass Unterklassen, aber nicht verhindern den Bau.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Warum nicht einfach einen öffentlichen APIClass Eigenschaft singleton?
Dann Ihre Berufung Website sieht wie folgt aus:
Oder wenn Sie der Autor des API-Klasse, könnte man es ein singleton selbst, statt wickelte Sie in ein singleton:
API-Aufruf:
Hier ist die offizielle Microsoft-Ansatz.
Die Schönheit der singleton ist, dass Sie verwenden können, und greifen Sie überall in Ihrem code ohne das erstellen einer Instanz der Klasse. In der Tat, es ist die raison d ' etre, eine einzelne Instanz einer Klasse z.B.
Singleton.Instanz.Meinwert und Singleton.Instanz.DoSomething();
Würden Sie nicht die Klasse instanziiert werden - die Muster, die Sie verwenden im Grunde erzeugt sich selbst das erste mal es verwendet wird. Der Vorteil der Methode, die Sie verwenden ist, dass es thread-sicher (wird nur einmal instanziieren, egal wie viele threads versuchen, darauf zuzugreifen), faul (es wird nicht instanziiert, bis Sie versuchen, Zugriff auf die Singleton-Klasse), und einfach in der Umsetzung.
Alles, was Sie tun müssen, ist zu tun:
Oder, alternativ: