Laden...

Anfänger: Statische Funktinonen die auf Singleton zugreifen

Erstellt von MillionsterNutzer vor 16 Jahren Letzter Beitrag vor 16 Jahren 1.682 Views
M
MillionsterNutzer Themenstarter:in
235 Beiträge seit 2005
vor 16 Jahren
Anfänger: Statische Funktinonen die auf Singleton zugreifen

Hi!

Ich denke es dürfte nicht schaden, wenn ich euch die Problematik die meiner Frage zugrunde liegt zunächst einmal etwas ausführlicher beschreibe. Nur vorne weg, es handelt sich hier weniger um ein Problem als vielmehr um eine Designfrage:

Meine Aufgabe ist es eine bereits vorhandene Dll zu ersetzen mit der man bisher Operationen auf bestimmte physikalische Einheiten ausführen konnte. Ein wichtiger Apekt der neuen Bibliothek ist, dass diese sich nicht nur bestimmte Einheiten beschränken soll, sondern erweiterbar sein soll. Das führt dazu, das die Einheitsdefinitionen, Umrechnungsfaktoren, etc. nicht mehr hart codiert werden können sondern aus einem XML-File ausgelesen werden können. Klar gibt es auch hier ein Standard XML-file, dass ich als eingebettete Resource im Projekt mit eingebunden habe, aber theoretisch könnte es den Fall geben das die zukünftige Dll für Sonderfälle auf eine extra XML-Datei zugreifen müsste.

Diese Sachlage hat also dazu geführt, dass ich bei meiner neuen Dll nicht mal einfach nur so mit statischen Methoden arbeiten kann, da ich für meine Operationen zunächst einmal die Definitionen einlesen muss. Damit das jedoch nicht für jede Operation aufs neue geschieht nutze ich eine Instanz die ggf. schon im Konstruktor einmalig ihre XML-Datei einliest und dann die einzelnen Operationen nach außen hin öffentlich zur Verfügung stellt. - Eigentlich wäre hier schon eine akzeptable Lösung vorhanden, aber ich habe die Sache noch etwas weiter gesponnen:

Zunächst habe ich das Singlton-Pattern auf meine Klasse angewandt, so dass nun immer nur eine Instanz meiner Klasse exisitiert und damit mehrfach-Instanzierungen und damit ein erneutes Einlesen der Definitionen verhindert wird.
Dabei kam ich auf die Idee, dass ich nun doch statische Methoden in meiner Dll definieren könnte, die beim Aufruf über das Singleton sich einfach nur die aktuelle Instanz holen und die übergebenen Parameter an die normalen Methoden weitergeben. Das hätte den Vorteil das die "Anwender" der Dll sich wie gewohnt der statischen Methoden bedinenen könnten (zumindest wenn die Standarddefinitionen ausreichen).

Tatsächlich scheint dieser Ansatz auch zu funktionieren: Selbst wenn ich unterschiedliche der neuen, statischen Methoden mehrfach aufrufe, so wird nun immer die selbe Instanz verwendet, so dass also eigentlich alles traumhaft funktioniert. Aber nun zu meinen Fragen:

  1. Ist dieser Ansatz so überhaupt in Ordnung? Ich habe soetwas noch nie verwendet und bin mir nun nicht sicher ob solch ein "Design" überhaupt "korrekt" ist oder ob es vielleicht irgendwelche unerwünschte Nebeneffekt birgt (Was "saubere" Programmierung angeht bin ich leider ein Anfänger).

  2. Warum und wie lange bleibt denn die Instanz meiner Dll lebendig? Immerhin wird sie ja nicht "von außen" lebendig gehalten. Der Garbagecollector weiß doch eigentlich nie, ob die Instanz noch gebraucht wird oder nicht...

  3. Seit ich das Singleton implementiert habe bekomme ich folgende Kompiler-Warnung: "xyz.dll enthält keine Typen, die für COM interop registriert werden können." (Ja, die Dll sollte später dann auch COM-fähig sein). Leider kann ich mit dieser Meldung nicht wirklich etwas anfangen. Versteht von euch jemand was dies e Meldung zu bedeuten hat?

Grüße!!!

6.862 Beiträge seit 2003
vor 16 Jahren

Ich denke das Singleton ist vollkommen fehl am Platz, weil du willst ja nicht eine Instanz, sondern du willst das die Daten nur einmal eingelesen werden. Genauso beißt sich das Singleton, das ja eine Instanz liefert damit, dass du statische Methoden benutzt um die Daten dann auszulesen aus einer Instanz was aber voll daneben ist, da statische Methoden gar nicht über die Instanz gehen, sondern über die Klasse. Weißt du wie ich das meine(hoffe hab dein Vorhaben da richtig verstanden)

Was du also brauchst ist etwas was pro Klasse nur einmal ausgeführt wird(Deine Daten einlesen) und dann willst du per statische Methoden drauf zugreifen.

=> Statischer Konstruktor

Gibts seit .Net 2.0 hoffe des verwendest du, weil das ist imo genau für dein Vorhaben geeignet. Dort würdest du die Daten einlesen und könntest dann per statische Methoden drauf zugreifen und wie gewohnt arbeiten.

Baka wa shinanakya naoranai.

Mein XING Profil.

M
MillionsterNutzer Themenstarter:in
235 Beiträge seit 2005
vor 16 Jahren

Hi talla!

Danke für deinen Tip mit den statischen Konstruktoren, habe ich vorher nicht gekannt. Habe es natürlich gleich ausprobiert und siehe da, es scheint mir tatsächlich die elegantere Variante zu sein. Allerdings bin ich immer noch etwas beunruhigt:
Ich habe zwei Methoden in meiner Klasse für das Laden der Definitionen:

LoadInternalDefinitions()
und
LoadExternalDefinitions(string filePath)

Die erstere wird per default, also auch in dem statischen Konstruktor geladen, hier kann ja nix schief gehen. Aber angenommen, einer der Kollegen braucht besondere Definitionen und nutzt hierzu die nun statische Methode LoadExternalDefinitions: Das habe ich ausprobiert und tatsächlich werden die externen Definitionen auch für spätere Aufrufe der anderen Operationen beibehalten. Aber wie lange? Wie kann ich sicherstellen dass das so bleibt so lange es sein muss?
Ich denke für diesen Fall müsste ich (und das würde auch die vorige Singleton-Variante betreffen) müsste ich einen normalen Konstruktor beibehalten, oder?

Grüße!!!

1.373 Beiträge seit 2004
vor 16 Jahren

Hallo,

Meiner Meinung nach solltest du etwas "objektorientierter" denken. Ich könnte mir durchaus eine Klasse vorstellen - nennen wir sie Calculator - mit verschiedenen Konstruktoren. Z.B. könnte der Default-Constructor eine Standarddefinition laden, ein andere Konstruktor könnte eine Dateinamen für die Definitionsdatei übergeben bekommen. Dann kann jeder Calculator sich auch noch eigene Sachen "merken" (Instanzvariablen) und arbeitet unabhängig voneinander. Wenn das Objekt noch was aufräumen soll, kann man wunderbar Dispose verwenden. Der vorgeschlagene "dauerstatische Zugriff" und das Singleton-Pattern halte ich für unpassend hier.


Calculator calc = new Calulcator();
calc.Foo();

Calculator calc2 = new Calculator("definitions.xml");
calc.Foo();

Das ist einfach, verständlich und dürfte gut erweiter- und wartbar sein. Denk mal einen Schritt weiter: verpass dem Calculator ein Interface (ICalculator). Erstelle und speichere irgendwo in der Anwendung eine ICalculator-Instanz und lass den Rest der Anwendung diese Schnittstelle verwenden. Jetzt kannst du nicht nur eine andere Definitions-Datei laden, sondern die Implementierung von Calculator komplett umkrempeln und zur Laufzeit austauschen, ohne dass der Rest der Anwendung davon betroffen ist. Sagt Hallo zum Strategy-Pattern 🙂

Grüße,
Andre

P.S.: Das Singleton-Pattern in einer Bibliothek ist eine ganz heikle Sache. Sollte es nach langer, langer Überlegung keinen unumstößlichen Grund geben, dass von der Klasse nur ein einziges Objekt existieren darf, lass das Pattern aus der Lib raus. Du verbaust dir sonst diverse Möglichkeiten der Nutzung.

M
MillionsterNutzer Themenstarter:in
235 Beiträge seit 2005
vor 16 Jahren
Danke!

Hi talla, hi VizOne!

Wollte mich nur nochmal für eure Tips bedanken!

Werde mein Problem jetzt mit dem statischen Konstruktor lösen und dafür das Laden von externen Definitionen wegfallen lassen, so dass die ganze Sache auch wieder ein korrektes Anrecht auf ein statisches Dasein hat - hätte ich es beibehalten hätte ich VizOne wirklich zustimmen müssen.

DANKE!!!