DIServiceManager - Wie jetzt!?

Hier dreht sich alles um die auf der Webseite veröffentlichten Tutorials. // This forum is all about the APF tutorials.
Antworten
Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

DIServiceManager - Wie jetzt!?

Beitrag von dave » 23.09.2012, 18:16:46

Moin Moin, Hallo, Servus ;)

Ich habe mich nun doch dazu entschlossen, meine neue Manager-Komponente via DIServiceManager zu beziehen, da in naher Zukunft weitere Konfigurationen hinzu kommen werden und diese via DIServiceManager ja recht schnell einbindbar sind.

Ich habe mir dazu nun die Doku sowie das Tutorial im Wiki (Erzeugen des GORM via DI....) angesehen, aber so richtig schlau bin ich darausd noch nicht geworden. Leider sind im Tutorial viele Namespaces mit "..." ersetzt, wa sich in einem Tutorial hinderlich finde und den User da doch lieber ein konkretes Beispiel zeigen würde. Wie auch immer ... ;)

Ich möchte folgendes Lösen:
Ich bastel mir eine "BusinessManager"-Komponente, welche die verschiedenen Möglichkeiten, die der User dann so nutzen kann, in einer Komponente bündeln soll. Dies wären zum jetzigen Zeitpunkt die Verwaltung von Uploads/Bildern/Dateien sowie das Verwalten von Anzeigen.

Ich habe dazu zwei Datenbank-Tabellen: Datei und Werbung und nebenbei das UMGT, welches hier abe rnicht berücksichtigt werden soll, da das eine seperate Komponente ist.
In meiner Business-Komponente soll es nun diverse Methoden zum Schalten von Anzeigen, ändern derer, ändern von Uploads etc. geben. Diese Methoden sollen dann aus den verschiedenen Controllern aufgerufen werden. Soweit ist das ganze ja denke ich völlig logisch.

Nun sollen die beiden existierenden Configurationen via DIServiceManager meinem Business-Manager beigebracht werden. Wie mache ich das nun= Und wie halte ich das so flexibel, dass ich später weitere Konfigurationen für Datenbanktabellen hinzufügen kann?

Ich poste mal meine Konfiguration für den DIServiceManager. Soweit, wie ich das alles verstanden habe. Ich würde mich freuen, wenn wir das gemeinsam angehen könnten, sodass auch ich das Thema DIServiceManager verstehe und damit arbeiten kann. Danke! :)

config/sites/business/biz/CONTEXT/DEFAULT_serviceobjects.ini:

Code: Alles auswählen

[BusinessManager]
servicetype = "SINGLETON"
namespace = "sites::business::biz"
class = "BusinessManager"
init.gorm.method = "setORMapper"
init.gorm.namespace = "sites::business::biz"
init.gorm.name =  "GORM"

[GORM]
servicetype = "SINGLETON"
namespace = "modules::genericormapper::data"
class = "GenericORRelationMapper"
Weiter habe ich das Thema nicht verstanden :(

Wie ich nun den Manager im Controller hole, ist mit bewusst, das geht ja recht fix und einfach:

Code: Alles auswählen

$this->__businessmgr = $this->getDIServiceObject('sites::business::biz', 'BusinessManager'); 
Es wird daraufhin die Config im Ordner config/sites/business/biz/CONTEXT/DEFAULT_serviceobjects.ini geholt. Der eigentliche Manager wird ja via namespace und class definiert. Es wird anschliessend der GORM über die Methode im BusinessManager setORMapper gheolt. Dies kalppt bisher ohne Fehler, ohne 500 internal Server Error, allerdings erhalte ich nur eine weisse Seite als Ausgabe, das wars. Logisch, die Config ist recht unvollständig.

Wie gehts nun weiter?


[EDIT]
So sieht meine Config nun nach einigem Probieren und ausmerzen kleinerer Fehlerchen aus:

Code: Alles auswählen

[BusinessManager]
servicetype = "SINGLETON"
namespace = "sites::business::biz"
class = "BusinessManager"
init.gorm.method = "setORMapper"
init.gorm.namespace = "sites::business::biz"
init.gorm.name =  "GORM"

[GORM]
servicetype = "SINGLETON"
namespace = "modules::genericormapper::data"
class = "BaseMapper"
init.configure.method = "setup"
init.configure.namespace = "sites::business::biz"
init.configure.name =  "GORM-CONFIG"
init.rel.method = "addDIRelationConfiguration"
init.rel.namespace = "sites::business::biz"
init.rel.name =  "GORM-CONFIG-RELATION"
init.map.method = "addDIMappingConfiguration"
init.map.namespace = "sites::business::biz"
init.map.name =  "GORM-CONFIG-MAPPING"

[GORM-CONFIG]
servicetype = "NORMAL"
namespace = "modules::genericormapper::data"
class = "GenericORMapperDIDomainObjectsConfiguration"
conf.namespace.method = "setConfigNamespace"
conf.namespace.value = "modules::usermanagement::data"
conf.db.method = "setConnectionName"
conf.db.value = "database-2"

[GORM-CONFIG-MAPPING]
servicetype = "NORMAL"
namespace = "modules::genericormapper::data"
class = "GenericORMapperDIMappingConfiguration"
conf.namespace.method = "setConfigNamespace"
conf.namespace.value = "business::datei"
conf.affix.method = "setConfigAffix"
conf.affix.value = "datei"

[GORM-CONFIG-RELATION]
servicetype = "NORMAL"
namespace = "modules::genericormapper::data"
class = "GenericORMapperDIRelationConfiguration"
conf.namespace.method = "setConfigNamespace"
conf.namespace.value = "business::datei"
conf.affix.method = "setConfigAffix"
conf.affix.value = "datei"
Allerdings erhalte ich den Fehler, dass meine Datenbeankverbindung database-2 nicht injiziert werden konnte, weil es die Methode setConnectionName im GenericORMapperDIDomainObjectsConfiguration nicht gibt. Richtig, die gibts da nicht, was mache ich falsch?

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

Re: DIServiceManager - Wie jetzt!?

Beitrag von dr.e. » 23.09.2012, 22:50:17

Hallo dave,
Leider sind im Tutorial viele Namespaces mit "..." ersetzt, wa sich in einem Tutorial hinderlich finde und den User da doch lieber ein konkretes Beispiel zeigen würde. Wie auch immer ... ;)
Das Tutorial gibt keine konkreten Namespaces an, da es im Wesentlichen dem Anwender überlassen ist, wo er seine Komponenten ablegt und konfiguriert. Dass das natürlich etwas schwierig für den Einstieg ist, stimmt absolut! :roll: Ich denke der DIServiceManager verdient definitiv mehr Dokumentation. Lasst uns das mal vormerken.
Soweit ist das ganze ja denke ich völlig logisch.
Klingt vernünftig.
Ich würde mich freuen, wenn wir das gemeinsam angehen könnten, sodass auch ich das Thema DIServiceManager verstehe und damit arbeiten kann. Danke! :)
Sehr gerne!
Nun sollen die beiden existierenden Configurationen via DIServiceManager meinem Business-Manager beigebracht werden. Wie mache ich das nun= Und wie halte ich das so flexibel, dass ich später weitere Konfigurationen für Datenbanktabellen hinzufügen kann?
Ich versuche deine Absicht zu rezitieren. Sofern ich falsch liege, bitte korrigieren. Was möchtest du erreichen? Dein Manager benutzt den GORM und dieser wiederum benutzt unterschiedliche Konfigurationen, die du per dependency injection konfigurieren möchtest.

Um den richtigen "Weg" - bzw. Konfigurations-Abfolge - zu wählen, kannst du versuchen die Abhängigkeiten von deinem Service nach unten aufzuzeigen. Das bedeutet:

Code: Alles auswählen

Controller benötigt Manager
                            --> Manager genötigt GORM
                                                     --> GORM benötigt Mapping-Config
                                                     --> GORM benötigt Relation-Config
                                                     --> GORM benötigt Datenbank-Config/-Connection
Dieser Trail ist auch gleichzeitig deine Anweisung für die Erstellung der Konfiguration.
Wie gehts nun weiter?
Ich versuche den Weg mal Schritt für Schritt aufzubauen:

Für deinen Manager gilt - ohne Abhängigkeiten - folgende Konfiguration:

Code: Alles auswählen

[BusinessManager]
servicetype = "SINGLETON"
namespace = "sites::business::biz"
class = "BusinessManager"
Der Service definiert sich dabei durch den Sektions-Namen und dem Namespace in dem deine Konfiguration liegt. Du hast dafür sites::business::biz gewählt, natürlich zuzüglich der Parameter des gerade eingesetzten Konfigurationsmechanismus (präziser: ConfigurationProvider). Hiermit meine ich {ENVIRONMENT} (bei dir DEFAULT) und {CONTEXT}. Wenn du nun deinen Manager per

Code: Alles auswählen

$mgr = $this->getDIServiceObject('sites::business::biz', 'BusinessManager'); 
beziehen möchtest, wird eine Konfigurationsdatei

Code: Alles auswählen

config/sites/business/biz/{CONTEXT}/DEFAULT_serviceobjects.ini
mit obigem Inhalt erwartet. Soweit, so gut! :)

Um deinem Manager den GORM beizubringen hast du bereits eine Methode setORMapper() vorgesehen, die eine Initialisierung des Managers mit einem weiteren Service zulässt. Um dies vorzunehmen definierst du ja bereits einen Service GORM, der injiziert werden soll. Die hierzu notwendige Konfiguration ist wie folgt:

Code: Alles auswählen

[GORM]
servicetype = "SESSIONSINGLETON"
namespace = "modules::genericormapper::data"
class = "GenericORRelationMapper"
setupmethod = "setup"
conf.namespace.method = "setConfigNamespace"
conf.namespace.value = "modules::usermanagement::data"
conf.affix.method = "setConfigNameAffix"
conf.affix.value = "???"
conf.db.method = "setConnectionName"
conf.db.value = "???"
Beispiel siehe http://wiki.adventure-php-framework.org ... rsion_1.15.
Richtig, die gibts da nicht, was mache ich falsch?
In deiner Konfiguration erzeugst du den BaseMapper statt den GenericORRelationMapper, was dazu führt, dass einige Methoden nicht zur Verfügung stehen und die Initialisierung mit Hilfe der setup()-Methode nicht möglich ist. Die Anwendung von

Code: Alles auswählen

init.configure.method = "setup"
init.configure.namespace = "sites::business::biz"
init.configure.name =  "GORM-CONFIG"
funktioniert nicht, da setup() keine Argumente trägt, sondern nach der Konfiguration aufgerufen wird um den internen Zustand des GORM vor der Verwendung zu initialisieren.

Ich denke, ich sollte hier nochmal wie beim Front-Controller ein Timing-Modell zeichnen, das klar macht, was wann passiert. Kurz gesprochen geht der DIServiceManager wie folgt vor:
  • Auflösen des Services
    • Laden der Konfiguration
    • Lesen der Service-Definition
  • Erzeugen der Service-Implementierung
  • Injizierung der "einfachen" Konfiguration (=alle conf.*-Sektionen)
  • Injizierung aller "komplexen" Konfigurationen (=alle init.*-Sektionen)
  • Ausführen der unter setupmethod konfigurierten Methode zur Initialisierung des Service.
Letztere ist vor allem dann wichtig, wenn der interne Zustand nur nach Injektion aller Abhängigkeiten hergestellt werden kann (z.B. Datenbank-Verbindung).

Die Konfigurationen für GenericORMapperDIDomainObjectsConfiguration, GenericORMapperDIMappingConfiguration und GenericORMapperDIRelationConfiguration werden jeweils mit addDIDomainObjectsConfiguration(), addDIMappingConfiguration() und addDIRelationConfiguration() injiziert (jeweils in der genannten Reihenfolge). Du hattest für GenericORMapperDIDomainObjectsConfiguration die initDI()-Methode genutzt, die in 1.15 garnicht mehr existiert.

Ich hoffe das hilft dir etwas weiter!

PS: ja, dafür brauchen wir eine bessere Dokumentation. :D
Viele Grüße,
Christian

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: DIServiceManager - Wie jetzt!?

Beitrag von dave » 24.09.2012, 10:38:56

Guten Morgen,

danke Christian für das ausführliche Feedback. Ich bin nun bereits ein Stück weiter gekommen und einen Grossteil deiner Ausführungen konnte ich nachvollziehen, da ich mir das so bereits gedacht habe bzw. ich es so verstanden habe.

Ich hab nun etwas an meiner Config weiter gebastelt, allerdings gibt es noch immer ein Problem:
Angeblich kann die Datenbank-Verbindung nicht aufgebaut werden, dass es die Config-Sektion "" nicht gibt. Das stimmt auch, aber ich frage mich, wieso meine Angabe "database-2" nicht übernommen wird.

Hier meine bisherige Config (abgekürzt):

Code: Alles auswählen

[GORM]
servicetype = "SINGLETON"
namespace = "modules::genericormapper::data"
class = "GenericORRelationMapper"
setupmethod = "setup"
conf.namespace.method = "setConfigNamespace"
conf.namespace.value = "business::werbung"
conf.affix.method = "setConfigNameAffix"
conf.affix.value = "werbung"
conf.db.method = "setConnectionName"
conf.db.value = "database-2"

init.rel.method = "addDIRelationConfiguration"
init.rel.namespace = "sites::business::biz"
init.rel.name =  "GORM-CONFIG-RELATION"
init.map.method = "addDIMappingConfiguration"
init.map.namespace = "sites::business::biz"
init.map.name =  "GORM-CONFIG-MAPPING"
Ich lade erstmal als Ahuptbestandteil die datenabkTabelle "Werbung", um später dann weitere via addDIRelationConfiguration etc. hinzu zu fügen. Soweit so gut. Allerdings kalppt es mit dem
conf.db.method = "setConnectionName"
conf.db.value = "database-2"
nicht. Warum?

dr.e. hat geschrieben:Du hattest für GenericORMapperDIDomainObjectsConfiguration die initDI()-Methode genutzt, die in 1.15 garnicht mehr existiert.
Sowas habe ich mir bereits gedacht aber ich wusste nicht, womit ich das ersetzen soll. Die Beispiele in der Doku und im Wiki sind nicht angepasst und das Guestbook2009 sowie das UMGT sind nicht so komplex.
dr.e. hat geschrieben: PS: ja, dafür brauchen wir eine bessere Dokumentation. :D
Das soll nicht das Problem werden. Sobald ich das verinnerlicht habe, schreibe ich ein Tutorial ins Wiki (welches ich auch versuche, aktuell zu halten ^^).

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

Re: DIServiceManager - Wie jetzt!?

Beitrag von dr.e. » 24.09.2012, 13:57:56

Hallo dave,

deine Konfiguration ist auf den ersten Blick absolut richtig. Ich möchte jedoch einen Bug nicht ausschließen. Kannst du mal mit dem Debugger in die setConnectionName() bzw. setup() reinschauen? Vielleicht ist es ein fehlerhafter Zeilenumbruch?
Viele Grüße,
Christian

Benutzeravatar
jwlighting
Beiträge: 466
Registriert: 14.07.2010, 14:23:58
Wohnort: LK Oldenburg
Kontaktdaten:

Re: DIServiceManager - Wie jetzt!?

Beitrag von jwlighting » 24.09.2012, 18:09:43

Zum Thema DIServiceManager ist auch folgender Abschnitt in der Migrationsdoku wichtig:

http://wiki.adventure-php-framework.org ... iceManager


Das sollten wir dringend in die Komponenten-Dokumentation mit aufnehmen!!

LG :)
Jan

Menschen irren - Politiker sind Menschen.
Für den Norddeutschen ist 1kW = 2 Pfund Schlick.

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: DIServiceManager - Wie jetzt!?

Beitrag von dave » 25.09.2012, 10:41:12

Moin Moin!

Heute Morgen habe ich mir das nochmal angesehen, auch den Beitrag zur Migration. Ich habe daraufhin den GORM auf neusten Stand aus dem SVN gebracht.

Ich habe mir nochmal meine Methode setORMapper im BusinessManager angesehen und da lag der Hund begraben. Ich habe da noch ein wenig Müll drin gehabt, wodurch der ConnectionKey mit "" überschrieben wurde. Dass ich einfach nur die Instanz der GORM fertig aufbereitet erhalte, wusste ich noch nicht, habe ich aber vom UMGT her "geklaut".

Nun passt alles soweit und ich werde mich melden, sobald ich wieder auf Probleme stosse. Der erste Eintrag in die DB hat besten geklappt :D

Da der Beitrag im Wiki mit den einzelnen Methoden nicht mehr ganz zum aktuellen Stand passt, ist es in Ordnung, wenn ich das etwas aktualisiere? Das hätte mich nämlich auch sicher weiter gebracht und ich wäre nicht bei "initDI" (was es gar nicht mehr gibt) hängen geblieben.

Danke für eure Hilfe, echt spitzenmässig! :)


[EDIT]
Eine Frage bleibt noch:
Wie kann ich neben meinen Konfigurationen für die Datenbanktabellen Datei und Werbung noch mehr Konfigurationen einfügen? Ich habe bereits versucht, meine Sektionen

Code: Alles auswählen

[GORM-CONFIG-MAPPING]
[GORM-CONFIG-RELATION]
einfach mit weiteren

Code: Alles auswählen

; Conf UMGT
conf.namespace.method = "setConfigNamespace"
conf.namespace.value = "modules::usermanagement::data"
conf.affix.method = "setConfigAffix"
conf.affix.value = "umgt"
zu erweitern, allerdings scheint immer nur die letzte Angabe bearbeitet zu werden, denn die vorherigen Angaben zur "Datei" werden nicht mehr gefunden bzw. sind diese fdem GORM jetzt nicht mehr bekannt.

Hintergrund: Ich möchte die Beziehungen zwischen den Objekten Datei - User sowie Werbung - User sichern, damit jeder User nur auf seine Daten Zugriff hat, bzw. ich das besser unterscheiden kann. Nun möchte ich allerdings nicht die gesamte UMGT Config rüber kopieren sondern diese mit einfliessen lassen.

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

Re: DIServiceManager - Wie jetzt!?

Beitrag von dr.e. » 25.09.2012, 21:06:43

Hi dave,
Da der Beitrag im Wiki mit den einzelnen Methoden nicht mehr ganz zum aktuellen Stand passt, ist es in Ordnung, wenn ich das etwas aktualisiere?
Nur zu! Ich versuche im Rahmen des 1.16er Releases einige Punkte in der offiziellen Doku zu bereinigen.
Danke für eure Hilfe, echt spitzenmässig! :)
Freut mich! :)
Hintergrund: Ich möchte die Beziehungen zwischen den Objekten Datei - User sowie Werbung - User sichern, damit jeder User nur auf seine Daten Zugriff hat, bzw. ich das besser unterscheiden kann. Nun möchte ich allerdings nicht die gesamte UMGT Config rüber kopieren sondern diese mit einfliessen lassen.
Das geht mit weiteren Mapping- und Relation-Konfigurationen, die du mit mehrfachen

Code: Alles auswählen

init.rel-*.method = "addDIRelationConfiguration"
init.rel-*.namespace = "sites::business::biz"
init.rel-*.name =  "..."
init.map-*.method = "addDIMappingConfiguration"
init.map-*.namespace = "sites::business::biz"
init.map-*.name =  "..."
injizierst. Für jede Konfiguration erstellst du einen Service und injizierst diesen jeweils mit addDIRelationConfiguration() bzw. addDIMappingConfiguration() in den GORM.

Soweit klar oder soll ich dir ein Beispiel aufzeigen?
Viele Grüße,
Christian

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: DIServiceManager - Wie jetzt!?

Beitrag von dave » 26.09.2012, 10:03:29

dr.e. hat geschrieben:Soweit klar oder soll ich dir ein Beispiel aufzeigen?
Alles klar, habe es eben umgesetzt und es funktioniert einwandfrei! Klasse, damit lässt sich wirklich sehr einfach und schnell eine weitere Konfiguration "on the fly" integrieren, wie es in der Doku steht. Jetzt kann ich das sogar glauben ;)

Das Tutorial habe ich im Wiki schonmal angelegt, aber ich werde dazu im Moment noch nicht kommen. Habe ne Schreib-Blockade ;) Da ich den gesamten Oktober wohl-verdienten Urlaub habe, denke ich, werde ich das zu dieser Zeit zwischendrin mal angehen.
Die Passagen im Wiki zum DIServiceManager ab 1.15 sind angepasst.

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

Re: DIServiceManager - Wie jetzt!?

Beitrag von dr.e. » 26.09.2012, 21:58:58

Hallo dave,

freut mich, dass du das Thema erfolgreich abschließen konntest. Der DISM ist ja auch ein vernünftiges Tool, nur fehlt eben die Doku. Danke, dass du dich drum kümmern möchtest & schon mal schönen Urlaub! :)
Viele Grüße,
Christian

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast