Verwendung von Singleton und SessionSingleton

Das Forum soll der Ablage von Lösungen für immer wieder auftauchende Problemstellungen dienen. // This forum contains solutions to problems that frequently occur.
Antworten
Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Verwendung von Singleton und SessionSingleton

Beitrag von Screeze » 19.09.2009, 12:46:11

Dieser Beitrag wurde aus dem Thread de/viewtopic.php?f=5&t=192 extrahiert.

Ich hab die userdaten jetzt im userSessionManager untergebracht und mittels __sleep dann vor der speicherung abgefangen.

Allerdings hab ich beim nächsten seitenrequest ein Problem.
Wenn ich den User setze, wird automatisch die methode check() aufgerufen, die den user anhand seiner Id läd und das userobject speichert.
Das funktioniert problemlos.
Beim nächsten request lade ich wieder den userSessionManager und rufe einmal check() auf, um die aktualität der daten zu prüfen.

Code: Alles auswählen

$uSM = &SessionSingleton::getInstance('userSessionManager');
$uSM->check();
Das wirft komischerweise folgenden fehler:
Error!

Error-ID: 66867254a04931374ebce0737dd55b36
Message: [configurationManager->getConfiguration()] Requested configuration with name "DEFAULT_umgtconfig.ini" cannot be loaded from namespace "modules::usermanagement" with context ""!
Number: 256
File: E:\xampp\APF\core\configuration\configurationManager.php
Line: 269
Ich nehme an hier fehlt der context, aber ich kann mir nicht erklären wieso? es hat sich ja eigentlich nichts geändert, und der aufruf von check() vorher war ja problemlos....

der stacktrace kommt u.a. beim userSessionManager bei der zeile:

Code: Alles auswählen

$uM = &$this->__getAndInitServiceObject('modules::usermanagement::biz','umgtManager','Default');
vorbei.


edit: Ok der context is ja im Objekt gespeichert, und geht demnach verloren bei der speicherung nehme ich an, weshalb ich die sleep funktion so angepasst habe:

Code: Alles auswählen

return array('__userId', '__lastAction', '__Attributes', '__Children', '__Context', '__Language', '__ObjectID', '__ParentObject', '__ServiceType');
Das sollte ja alle gespeicherten Daten des Objects speichern, auch den Context, aber leider zeigt es keine wirkung.

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: usermanagement - sessionSingleton

Beitrag von dr.e. » 19.09.2009, 17:59:04

Hi Screeze,

an sich sollte deine zweite Variante funktionieren, ich vermute jedoch, dass irgendwo in der Kette der Aufrufe Context nach dem Deserialisieren verloren geht. Um das genau herauszufinden, kannst du ja mal in den Komponenten - angefangen vom userSessionManager - die Aufrufe Debuggen / ein echo $this->__Context einbauen.

Um sicherzustellen, dass auch nach dem Deserialisieren alle relevanten Informationen in den Objekten enthalten sind, kannst du deinen userSessionManager so erzeugen:

Code: Alles auswählen

$uSM = &$this->__getServiceObject('modules::usermanagement::biz','userSessionManager','SESSIONSINGLETON');
Sollte das nichts helfen, dann lass uns deinen Anwendungs-Fall genauer analysieren, dann könnte es auch ein Bug bei der Deserialisierung sein.
Viele Grüße,
Christian

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: usermanagement - sessionSingleton

Beitrag von Screeze » 19.09.2009, 18:21:32

Hmm also ich hab grad schon was versucht:

Am anfang von check() hab ich this->__Context ausgeben lassen.

Beim 1. seitenaufruf der session war der context sofort leer.
auch bei jedem weiteren aufruf.

Ich hab dann mal den context am anfang von check() manuell gesetzt. und 1mal aufgerufen. -> funktioniert logischerweise.
dann hab ich den aufruf wieder rausgenommen, aber die selbe session behalten. Bei jedem weiteren aufruf blieb der context erhalten. (also serialisierung und deserialisierung klappt problemlos)

Das bedeuted wohl, dass der context zu beginn nicht richtig gesetzt wird. Der sollte aber doch automatisch gesetzt werden oder?

edit:
Hat die Klasse nicht automatisch ein parentObject?
denn __ParentObject ist auch null (wollte mal probieren ob ich den context vom parent-object einfach in den normalen context kopieren kann als workaround)

edit2:
anscheinend funktioniert die instanzierung mit

Code: Alles auswählen

$uSM = &$this->__getServiceObject('modules::usermanagement::biz','userSessionManager','SESSIONSINGLETON');
besser, denn da wird der context erzeugt...

Ist das ein beabsichtigtes verhalten, oder funktioniert bei dieser erzeugung

Code: Alles auswählen

$uSM = &SessionSingleton::getInstance('userSessionManager');
etwas nicht wie es soll?

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: usermanagement - sessionSingleton

Beitrag von dr.e. » 19.09.2009, 21:10:18

Hallo Screeze,
anscheinend funktioniert die instanzierung mit
$uSM = &$this->__getServiceObject('modules::usermanagement::biz','userSessionManager','SESSIONSINGLETON');
besser, denn da wird der context erzeugt...
Als ich nach meinem Post nochmal drüber nachgedacht hatte, war mir fast klar, dass es diese Ursache haben muss. Der Grund ist folgender:

Die Klasse Singleton und SessionSingleton kümmern sich um die Erzeugung der Objekte selbst, nicht um die Initialisierung. Im Fall von Singleton wird die Klasse im Kontext des aktuellen Requests zurückgeliefert - egal, welche Werte dieser Instanz mitgegeben wurden -, nutzt du SessionSingleton, gilt dieses für die komplette Session.
Im APF ist es jedoch so, dass Objekte nicht nur erzeugt, sondern dabei auch initialisiert werden (Context, Sprache, ...). Dies passiert jedoch nur, wenn auch die entsprechende Factory-Methode genutzt wirde. Hierunter fallen __get[AndInit]ServiceObject() und getDIServiceObject() sowie die Parser-Methoden des Page-Controller. Diese erzeugen ein Objekt mit Hilfe der Singleton- und SessionSingleton-Klassen und präparieren es für deinen Einsatz. Nur so ist sichergestellt, dass dieses über alle notwendigen APF-Umgebungs-Informationen verfügt.
Sofern du nicht auf diese Informationen angewiesen bist, kannst du natürlich jederzeit Singleton und SessionSingleton "in natura" nutzen, sofern du diese benötigst, solltest du immer auf __get[AndInit]ServiceObject() und getDIServiceObject() zurückgreifen.

Ich hoffe, damit ist die Vorgehensweise des APF etwas verständlicher. :) Falls nicht, einfach nochmal Fragen stellen.
Viele Grüße,
Christian

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: Verwendung von Singleton und SessionSingleton

Beitrag von Screeze » 19.09.2009, 21:19:29

Ok wenn mans weiß verständlich, aber ein hinweis in der doku bei singleton und sessionSingleton wäre villeicht angebracht in dem zusammenhang, denn von dort bin ich ausgegangen ;)

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: Verwendung von Singleton und SessionSingleton

Beitrag von dr.e. » 19.09.2009, 23:23:11

Hi,

baue ich in die Doku für Release 1.11 ein. :)
Viele Grüße,
Christian

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast