2013-02-14 5 views
8

Ich versuche Service Manager für meine Entitätsklasse zu verwenden, aber ich weiß nicht, wie ich das am besten machen soll.Die beste Methode, ServiceManager in der Modellklasse zu verwenden?

Es ist einfach auf einem Controller, weil wir Service-Manager mit aufrufen können: $ this-> getServiceLocator();

Aber meiner Entitätsklasse, auch wenn ich ServiceLocatorAwareInterface implementiert, kann ich retieve Servicemanager, weil meine Entitätsklasse mit dem Service-Manager nicht nennen wird:

Also, was ist der beste Weg:

1 - Übergeben Sie ServiceManager in meiner Entitätsklasse von meinem Controller aus 2 - Verwenden von ServiceManager zum Erstellen meiner Entitätsklasse 3 - ...?

am besten, um mein Problem zu verstehen, das ist mein Code, der nicht funktioniert:

Meine Entitätsklasse:

class Demande extends ArraySerializable implements InputFilterAwareInterface { 
/../ 
    public function getUserTable() { 
    if (! $this->userTable) { 

     $sm = $this->getServiceLocator();//<== doesn't work ! 
     $this->userTable = $sm->get ('Application\Model\UserTable'); 
    } 
    return $this->userTable; 
} 

Antwort

18

ich injizieren würde nicht die Servicemanager in Ihr Modell (auch wenn Sie können). Ich würde lieber den ServiceManager bekommen, um Ihr Modell für Sie zu bauen und alles, was Sie brauchen, direkt in das Modell zu injizieren.

Service-Config:

'factories' => array(
    'SomethingHere' => function($sm) { 
     $model= new \My\Model\Something(); 

     return $model; 
    }, 
    '\My\Model\Demande' => function($sm) { 
     $model= new \My\Model\Demande(); 
     /** 
     * Here you use the SM to inject any dependencies you need 
     * into your model/service what ever.. 
     */ 
     $model->setSomething($sm->get('SomethingHere')); 

     return $model; 
    }, 
    /** 
    * Alternatively you can provide a class implementing 
    * Zend\ServiceManager\FactoryInterface 
    * which will provide an instance for you instad of using closures 
    */ 
    '\My\Model\DemandeDefault' => '\My\Model\DemandeFactory', 

Platz alle Ihre Abhängigkeiten innerhalb des Service Manager Config, und dann, dass alle Abhängigkeiten in Ihre Modelle zu injizieren verwenden, Dienstleistungen usw. für Sie.

Ein Beispiel Factory-Klasse, wenn Sie die Factory-Methode verwenden möchten, anstatt Verschlüsse:

DemandeFactory.php

use Zend\ServiceManager\FactoryInterface; 
use Zend\ServiceManager\ServiceLocatorInterface; 

class DemandeFactory implements FactoryInterface 
{ 
    /** 
    * Create a new Instance 
    * 
    * @param ServiceLocatorInterface $serviceLocator 
    * @return Demande 
    */ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $config = $serviceLocator->get('Config'); // if you need the config.. 
     // inject dependencies via contrustor 
     $model = new \My\Model\Demande($serviceLocator->get('SomethingHere')); 
     // or using setter if you wish. 
     //$model->setSomething($serviceLocator->get('SomethingHere')); 

     return $model; 
    } 
} 

Ein Beispiel Modell Sie über den Service Manager zu instanziiert versuchen.

Demande.php

class Demande 
{ 
    protected $_something; 

    /** 
    * You can optionally inject your dependancies via your constructor 
    */ 
    public function __construct($something) 
    { 
     $this->setSomething($something); 
    } 

    /** 
    * Inject your dependencies via Setters 
    */ 
    public function setSomething($something) 
    { 
     $this->_something = $something; 
    } 

    // Something will be injected for you by the Service Manager 
    // so there's no need to inject the SM itself. 
} 

In Ihrem Controller:

public function getDemande() 
{ 
    if (! $this->_demande) { 
     $sm = $this->getServiceLocator(); 
     $this->_demande = $sm->get ('\My\Model\Demande'); 
    } 
    return $this->_demande; 
} 

Sie konnten die SergiceManager/Servicelocator in Ihre Modelle injizieren, aber dann wird Ihre Modelle auf dem Servicelocator abhängen.

+2

Sehr nützliche Antwort! Ein weiterer Grund, den ServiceManager nicht in das Modell zu injizieren, ist, dass wir auf diese Weise unser Objekt nicht serialisieren können (wegen der Schließung des ServiceManagers). Und so können wir keine Modelle in der Sitzung speichern. –

+1

Das Einzige, was hinzugefügt werden muss, ist, dass du 'Closure' nicht zu viel benutzen solltest. Schreibe stattdessen Factory-Klassen. Dies erhöht die Gesamtleistung, da die Klassen nur bei Bedarf instanziiert werden. Alle Closures werden bei jeder Anfrage instanziiert. – Sam

+1

Noch eine Sache: Wenn einige Abhängigkeiten unbedingt ** erforderlich sind, ist es sehr empfehlenswert, '__construct()' oder Injektion statt Setter-Injection – Sam

Verwandte Themen