2011-01-04 3 views
3

Ich habe eine Klasse, die durch eine andere Bibliothek instanziiert wird. Ich habe keine Kontrolle über diesen Bibliothekscode, muss aber trotzdem sicher sein, dass nicht mehr als eine Instanz meiner Klasse erstellt werden kann.Wie Singleton eine Lazy instanziierte Klasse machen?

Ist es möglich? Wie ?

+0

Initiiert die Bibliothek die Klasse "said"? – adatapost

+0

Ich benutze 'Lazy hisClass;' wenn 'hisClass.Value' aufgerufen wird, wird der Standardkonstruktor meiner Klasse aufgerufen. Obwohl 'Lazy' die gleiche Instanz beim nächsten Zugriff auf 'hisClass.Value' zurückgeben würde, möchte ich aber sicherstellen, dass niemand mehrere Instanzen von 'myClass' erstellen kann. – Xaqron

Antwort

4

Einige einfache Lösungen zu dieser Frage verbirgt sich einige Probleme, für ein volles Verständnis dieser Angelegenheit ich

http://www.yoda.arachsys.com/csharp/singleton.html

, die mit einer optimalen Lösung schließt

das Lesen des folgenden Artikel empfehlen
public sealed class Singleton 
{ 
    Singleton() 
    { 
    } 

    public static Singleton Instance 
    { 
     get 
     { 
      return Nested.instance; 
     } 
    } 

    class Nested 
    { 
     // Explicit static constructor to tell C# compiler 
     // not to mark type as beforefieldinit 
     static Nested() 
     { 
     } 

     internal static readonly Singleton instance = new Singleton(); 
    } 
} 
+0

Ich habe diesen Artikel gelesen. Es geht um mögliche Implementierungen von 'Singleton' mit' C# 'und nichts mit' Lazy' Instanziierungsproblem. Das Problem ist, dass der Aufrufer nicht über die Eigenschaft 'Instance' auf meine Klasse zugreift. Ich muss etwas im Konstruktor machen. Das ist alles was ich habe. – Xaqron

+0

@ Xaqron OIC. Sie benötigen eine Proxy-Klasse, die mehrfach instanziiert werden kann und dieselbe Schnittstelle wie Ihre Klasse implementiert. Dann ruft diese Proxy-Klasse die Singleton-Methoden auf. –

+0

+1 Nur wegen der Tatsache, dass Sie auf eine Webseite verwiesen haben, die davon redet, dass Javas Double Checked Locking kaputt ist. –

1

Wenn Sie den Konstruktor Ihrer Klasse aufrufen, können Sie nur eine Ausnahme im Konstruktor auslösen, wenn Sie feststellen, dass zuvor eine Instanz erstellt wurde. Da Sie die andere Bibliothek nicht steuern können, können Sie keine Factory-Methode oder statische Eigenschaft verwenden, die normalerweise den Zugriff auf ein Singleton steuert.

Je nach Situation können Sie auch einen Lightweight-Proxy verwenden, der eine Singleton-Instanz umschließt. In diesem Beispiel kann eine beliebige Anzahl von MyObjectProxy erstellt werden, aber alle verschieben ihre Implementierung auf eine einzelne Instanz von MyObject.

public class MyObject { 

    internal MyObject() { 
    } 

    private int _counter; 

    public int Increment() { 
     return Interlocked.Increment(ref _counter); 
    } 

} 

public class MyObjectProxy { 

    private static readonly MyObject _singleton = new MyObject(); 

    public MyObjectProxy() { 
    } 

    public int Increment() { 
     return _singleton.Increment(); 
    } 

} 
+0

Und wo' MyObjectProxy' 'MyObject' zurückgibt? – Xaqron

+0

In meinem Beispiel gibt MyObjectProxy MyObject nicht zurück. Es delegiert seine Aufrufe einfach an das untergeordnete MyObject, das ein Singleton ist. Anrufer können so viele MyObjectProxy-Instanzen erstellen, wie sie möchten, aber sie erhöhen immer den gleichen Zähler. – Josh

+0

Das ist gut, wir haben jetzt eine Instanz, aber diese Bibliothek wird etwas mit 'myClass' tun, das' ICallerLibraryInterface' implementiert. Auf diese Weise bekam ich ein größeres Problem, da 'MyObjectProxy' nicht mit dieser Bibliothek funktioniert. – Xaqron