Frage

Ich implementiere einen Benachrichtigungsrahmen für eines meiner Projekte. Da ich möchte, dass es sehr generisch ist, kann der Benutzer mehrere Transportebenen verwenden, damit er sich nicht wirklich darum kümmert, eine Liefermethode (sagen wir WCF) oder eine andere (für z. B. Activemq). Die Schnittstelle, die der Benutzer hat, ist natürlich unabhängig von der Liefermethode (WCF oder Activemq). Dennoch implementiert die beiden Klassen (Verbraucher und Produzent) Singletons, sodass sie tatsächlich Standardkonstruktoren verwenden (dh keine Parameter). Mein Problem ist, dass ich einen Parameter haben möchte, die Liefermethode, die der Benutzer verwenden möchte. Aber soweit ich weiß, verwendet Singleton nur Standardkonstruktoren? Das ist normal, da es keinen Sinn gibt, Singletonen mit Parametern zu verwenden. Also, was sind meine Optionen hier? Nicht um einen Singleton zu schaffen? Erstellen Sie eine Methode, um die Liefermethode festzulegen?

Vielen Dank für Ihre Hilfe,

Sebastian

War es hilfreich?

Lösung

Sie können sicherlich Parameter mit Singletons haben, außer dass Sie ihn anstatt den Parameter in einen Konstruktor zu übergeben, sondern in die Methode getInstance () weitergeben. Ihr überschriebener Konstruktor muss natürlich für eine echte Singleton -Implementierung privat sein. Mein Beispiel ist in Java geschrieben, gilt aber auch für C#.

Beispiel:

Singleton s = Singleton.getInstance(42);

Im Singleton -Code:

private Singleton() {

}

private Singleton(int num) {
   //set num
}

public getInstance(int num) {
  //singleton code (calls the private non-default constructor if an object 
  //does not already exist) 
}

Andere Tipps

Es gibt einige Abhängigkeitsinjektionsrahmen wie Spring.net, die Ihnen helfen könnten. Sie können einen Parameter in einer Konfigurationsdatei für Ihren Singletons -Konstruktor effektiv übergeben.

Link zu einem Feder -Framework -Beispiel

Darf ich vorschlagen, dass Sie, wenn Sie zwei verschiedene Verhaltensweisen für Ihr Singleton benötigen, die Sie möglicherweise unterklassen möchten. Auf diese Weise erhalten Sie das Verhalten, das Sie wollen, indem Sie den Singleton des gewünschten Klassenverhaltens aufrufen.

Sie können dies einfach mit einem Abhängigkeitsinjektionsrahmen tun. Ich habe ein ähnliches Konstrukt in meinem aktuellen Projekt verwendet Mef. Alles, was erforderlich ist, ist die Verwendung der Konstruktionseinspritzoptionen und die Anmeldung und die Anbaugruppe der Abhängigkeit in den Katalog hinzuzufügen und sie korrekt zu verdrehen.

Eine andere Option besteht darin, eine Form der Initialisierungsfunktion zu haben, die Ihre Option übernimmt und die Singleton -Instanz konstruiert. Anstatt es beim ersten Zugriff zu konstruieren, können Sie es während des Initialisierungsaufrufs konstruieren. Der Nachteil hier ist, dass Sie sicherstellen müssen, dass Sie Ihr Singleton initialisieren, bevor Sie ihn verwenden (normalerweise zu Programmstart mit einer Konfigurationsdatei).

Eine ähnliche, aber weniger fehleranfällige Option besteht darin, nur den Singleton Lazy initialisieren zu lassen und ihm eine "Standard" -Option zu geben. Lassen Sie dem Anrufer eine statische Eigenschaft festlegen, um zu ändern, welche Option errichtet wird. Wenn sie vor der Konstruktion des Singletons festgelegt ist, erhalten Sie einen anderen Standard. Dies kann jedoch verwirrend sein, da Sie erneut sicherstellen müssen, dass Sie die Eigenschaft einstellen, bevor Sie auf das Singleton zugreifen, oder Sie ein unerwartetes Verhalten erhalten.

Ich weiß, dass es spät ist, die ursprüngliche Frage zu beantworten, aber ich hatte nur dieses Problem und hier ist, wie ich sie gelöst habe. Könnte nicht ideal sein, aber es scheint zu funktionieren. Ich habe eine Init -Methode erstellt, die aufgerufen werden muss, bevor ich versuchte, die Singleton -Instanz zu verwenden.

public void Init(/*parameters*/)
{
        if (_isInitialized)
        {
            throw new InvalidOperationException("Component is already initialized!");
        }
        //do your work here
}

Jeder andere Zugriff auf die Singleton -Instanz (Eigenschaften erhalten, festgelegt, Methodenaufrufe) wird eine ungültige Operationsausnahme auswerfen, die zeigt, dass das Objekt nicht initialisiert wurde.

Ich denke, das tut das, was ich brauche, ist weniger verwirrend als Getinstance (Params), da kein Missverständnis, was die Methode tut. Der Nachteil ist, dass es keine Kompilierungszeitfehler werfen wird, aber der erste Lauf ohne die Initialisierung wird eine Ausnahme ausgelöst, sodass er gut genug sein sollte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top