2016-05-05 6 views
2

Ich benutze Apigility, auf ZF2 gebaut. Sobald die Anfrage an den Controller gesendet wird, muss ich die richtige Adapter-Anforderung auswählen - basierend auf eingehenden Parametern.zend framework 2: Wie kann man Factory-Controller richtig in den Controller einspeisen, um verschiedene Mapper-Klassen zu erhalten?

Normalerweise wird Controller von ControllerFactory instanziiert, wo Sie alle Abhängigkeiten bereitstellen können, sagen wir, ich brauche eine Art Mapper-Klasse, die injiziert werden soll. Es ist einfach, wenn ich weiß, welches ich innerhalb des Controllers verwenden werde. Es ist problematisch, wenn der Controller entscheiden muss, welcher Mapper verwendet werden soll.

Lasst uns sagen Benutzer so etwas wie getStatus mit param anfordert 'adapter1' und ein anderer Benutzer dieselbe Aktion zugreift, aber mit param 'adapter2'.

Also, ich muss adapter1 Mapper OR adapter2 Mapper injizieren, die ähnliche Schnittstelle, aber anderen Konstruktor hat.

Wie ist der richtige Umgang mit dieser Situation?

Eine mögliche Lösung ist, eine Art von Factory-Methode zu liefern, die angeforderten Adapter zur Verfügung stellt, aber - mit dem SM Int der Modellklasse sollte vermieden werden.

Eine andere Möglichkeit besteht darin, SM direkt in der Aktion des Controllers zu verwenden, aber dies ist nicht der beste Ansatz, da ich die Logik für eine andere Aktion/Controller nicht wiederverwenden kann.

Wie bitte damit umgehen?

+0

Ich glaube, Sie in der Lage sind SM für den Zugriff auf Request-Objekt in Ihrem Betrieb verwenden. Also schnappen Sie sich einfach den Parameter und überprüfen Sie den Zustand, bevor Sie die Abhängigkeit von Ihrem Controller herstellen. Definieren Sie die Mapper-Schnittstelle bei Bedarf, wenn beide Adapter zur allgemeinen Schnittstelle gehören. –

+0

Das ist leider nicht der Fall. Scheint, dass in Apigility gefilterte Parameter nur verfügbar sind, nachdem die Aktion aufgerufen wurde, nicht im Konstruktor. Ich habe das als erste Option getestet :) – Ivan

Antwort

0

Sie könnten dafür Controller-Plugins verwenden.

So können Sie den Adapter in Ihrem Controller erhalten, wenn Sie es benötigen, ohne eine zu injizieren und ohne die gesamte Logik in die Fabrik hinzuzufügen. Der Adapter wird nur instanziiert, wenn Sie ihn in Ihrer Controller-Aktionsmethode anfordern.

Zuerst müssen Sie Ihre Controller Plugin-Klasse (Erweiterung Zend\Mvc\Controller\Plugin\AbstractPlugin) erstellen:

<?php 
namespace Application\Controller\Plugin; 

use Zend\Mvc\Controller\Plugin\AbstractPlugin; 

class AdapterPlugin extends AbstractPlugin{ 

    protected $adapterProviderService; 

    public function __constuct(AdapterProviderService $adapterProviderService){ 
     $this->adapterProviderService = $adapterProviderService; 
    } 

    public function getAdapter($param){ 
     // get the adapter using the param passed from controller 

    } 
} 

Dann eine Fabrik Ihren Dienst in der Klasse zu injizieren:

<?php 
namespace Application\Controller\Plugin\Factory; 

use Application\Controller\Plugin\AdapterPlugin; 

class AdapterPluginFactory implements FactoryInterface 
{ 
    /** 
    * @param ServiceLocatorInterface $serviceController 
    * @return AdapterPlugin 
    */ 
    public function createService(ServiceLocatorInterface $serviceController) 
    { 
     $serviceManager = $serviceController->getServiceLocator(); 
     $adapterProvicerService = $serviceManager>get('Application\Service\AdapterProviderService'); 
     return new AdapterPlugin($adapterProviderService); 
    } 
} 

Dann müssen Sie Ihr Plugin registrieren in Ihrem module.config.php:

<?php 
return array(
    //... 
    'controller_plugins' => array(
     'factories' => array(
      'AdapterPlugin' => 'Application\Controller\Plugin\Factory\AdapterPluginFactory', 
     ) 
    ), 
    // ... 
); 

Jetzt können Sie verwenden es in Ihrem Controller-Aktion wie folgt aus:

protected function controllerAction(){ 
    $plugin = $this->plugin('AdapterPlugin'); 
    // Get the param for getting the correct adapter 
    $param = $this->getParamForAdapter(); 
    // now you can get the adapter using the plugin 
    $plugin->getAdapter($param); 
} 

Lesen Sie mehr über Controller Plugins here in the documentation

+0

Vielen Dank für die Erklärung, scheint, dass dies die beste Option für mich sein wird. Ich akzeptiere die Antwort, nur bitte noch eine Frage: Denkst du, dass ich SM direkt in der getAdapter() -Methode des Plugins verwenden kann, anstelle von benutzerdefinierten AdapterProvider? – Ivan

+0

@Ivan, sicher, aber es wäre besser, wenn Sie Ihre Adapter direkt in das Controller-Plugin injizieren, wenn Sie es in der Fabrik instanziieren. – Wilt

+0

Das ist richtig, aber im Szenario, wo viele verschiedene Adapter verfügbar sind und nur wenige von ihnen benötigt werden - ist es vielleicht besser, sie nicht alle zu instanziieren, sondern nur angefordert .. es ist ein bisschen theoretische Frage, ich bin nur versuchen, besten Ansatz zu wählen :) Ich versuche, einige "Lazy-Load" Fabrik Ansatz zu finden, wenn Sie verstehen, was ich meine – Ivan

Verwandte Themen