Symfony Dependency Injection / eigene Services

Hallo, ich möchte gerne neuen Funktionen für Shopware (aktuelle Beta) entwickeln und diese über Composer als Paket modular einbringen (nicht per Pluginsystem!). Unter anderem möchte ich eigene Services im Container hinzufügen, die auch bestehende Services von Shopware injecten. Ich habe es bis jetzt nicht geschafft eine eigene YML / XML Datei hinzuzufügen ohne direkt in den Shopware -Dateien rumzueditieren. Könntet Ihr bitte hierzu eine Möglichkeit bieten? Der Kernel baut ja den Container zusammen ohne das man wirklich Einfluss drauf hat. Außerdem ist mir aufgefallen, dass Ihr die CLI-Commands relativ umständlich in die CLI-Application einbindet. Warum deklariert Ihr diese nicht als Services und holt sie dann anhand eines Tags heraus und added diese dann zur CLI-Application? Der Container ist ja in der CLI-Application vorhanden … Wäre cool, wenn Ihr mir weiterhelfen könntet. Ich finde es schonmal Klasse, dass Composer und CLI endlich den Weg in Shopware gefunden haben :sunglasses:

Ist zwar ein bisschen spät, aber vielleicht hilft es einstweilen: In einer Plugin-Bootstrap kann wie folgt der Container erweitert werden: $container = $this-\>collection-\>Application()-\>Container(); $container-\>set('my-service', new \Shopware\Plugins\Frontend\MyPlugin\Service\MyService()); Damit lassen sich immerhin innerhalb eines Plugins Services definieren, die dann wiederum in eigenen Controllern usw. innerhalb des gleichen Plugins benutzt werden können. Uns reicht das aktuell, weiter habe ich mich nicht reingefuchst.

Hi, das ist grundsätzlich richtig, hat aber den Nachteil, dass du die Instanz deines Services immer erzeugen musst, ohne zu wissen, ob sie im aktuellen Dispatch überhaupt benötigt wird. Du kannst deinen Service erst erzeugen, wenn er benötigt wird, indem du das InitResource-Event nutzt: Enlight_Bootstrap_InitResource_MEINEKOMPONENTE Ein Beispiel findest du hier: https://github.com/dnoegel/scd-2014-plu … source.php Schöne Grüße, Daniel

1 Like

Merci - funktioniert perfekt! Das ist ein meilenweiter Vorsprung :slight_smile:

Eine Frage tauchte noch auf: Gibt es auch die Möglichkeit, Hooks mittels eines Subscribers zu bearbeiten?

Hi, meinst du mit “bearbeiten” “sich darauf registrieren”? Dann: Ja :slight_smile: public static function getSubscribedEvents() { return array( 'sOrder::sSaveOrder::after' =\> 'afterOrder' ); } lG Daniel

Hierzu hätte ich noch neine ergänzende Frage. Und zwar ab wann steht der eigene Service im Dependency container zur Verfügung? So scheint er während dem Enlight_Controller_Front_DispatchLoopStartup im Registrierungsprozess für den Defaultsubscriber noch nicht zur Verfügung zu stehen und spuckt einen “Fatal error resource not found failure” aus. Obwohl der Resource Subscriber zuvor schon registiert wurde. /\*\* \* The default subscriber will always be used - in frontend, backend or CLI \*/ public function registerDefaultSubscriber() { $subscribers = array( // Registrierung des Resource Subrcibers mit dem onInitResourceMyService Listener new \Shopware\Plugins\MyPlugin\Subscriber\Resources($this-\>Application()-\>Container()), // Ein weiterer Subcriber der den Service bei Erzeugung mit bekommen soll new \Shopware\Plugins\MyPlugin\Subscriber\CoreHooks($this-\>get('myservice')), ); foreach ($subscribers as $subscriber) { $this-\>Application()-\>Events()-\>addSubscriber($subscriber); } } An anderere Stelle funktioniert dies einwandfrei. Beispielweise wenn if ($args-\>getRequest()-\>getModuleName() == 'backend') zutrifft.

Hi, ich denke, das ist ein Logik-Probleme: Dein zweiter Subscriber hängt ja vom ersten ab (wegen deines Services), beide Subscriber sind ja aber noch gar nicht registriert. Theoretisch musst du also erst den ersten Subscriber im System registrieren - und kannst dann deinen Service in weitere Subscriber injecten. Ehrlich gesagt, würde ich mir den Stress bei den Subscribern aber ein wenig sparen - die Subscriber sind ohnehin nur „glue code“ zwischen Shopware und deiner eigenen Applikationslogik - testen lassen die sich ohnehin relativ schlecht. Von daher dürfen die Subscriber mMn auch durchaus auf dem Container oder Shopware-Objekt als Service-Registry arbeiten (bei einigen Abhängigkeiten wie der Session oder dem Shop-Objekt kann das sogar zwingend nötig sein). Wichtiger ist, dass du aus den Subscribern relativ schnell in deine eigenen Services kommst und da sauber injectest. lG Daniel

1 Like