2013-02-14 40 views
8

मैं अपनी इकाई वर्ग पर सेवा प्रबंधक का उपयोग करने की कोशिश कर रहा हूं लेकिन मुझे ऐसा करने का सबसे अच्छा तरीका नहीं पता है।मॉडल क्लास में ServiceManager का उपयोग करने का सबसे अच्छा तरीका?

यह नियंत्रक पर आसान है क्योंकि हम सेवा प्रबंधक को कॉल कर सकते हैं: $ this-> getServiceLocator();

लेकिन, मेरी इकाई वर्ग में, भले ही मैं ServiceLocatorAwareInterface लागू करता है मैं ServiceManager retieve कर सकते हैं, क्योंकि मेरी इकाई श्रेणी सेवा प्रबंधक के साथ फोन नहीं है:

तो सबसे अच्छा तरीका क्या है:

1 - मेरे नियंत्रक 2 से मेरी इकाई वर्ग में सेवा प्रबंधक पास करें - मेरी इकाई वर्ग 3 - ... बनाने के लिए ServiceManager का उपयोग करना ...?

सबसे अच्छा मेरी समस्या को समझने के लिए है कि मेरे कोड है जो काम नहीं करता है:

मेरे इकाई वर्ग:

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; 
} 

उत्तर

18

मैं अपने मॉडल में ServiceManager इंजेक्षन नहीं होता है (हालांकि आप कर सकते हैं)। मैं आपके लिए अपना मॉडल बनाने के लिए ServiceManager प्राप्त करूंगा, और आपको सीधे मॉडल में जो भी चाहिए उसे इंजेक्ट करें।

सेवा कॉन्फ़िग:

'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', 

प्लेस सेवा प्रबंधक कॉन्फ़िग अंदर अपनी निर्भरता के किसी भी, और फिर उपयोग करें कि आप के लिए, सेवाओं आदि अपने मॉडल में किसी भी निर्भरता इंजेक्षन करने के लिए।

एक उदाहरण कारखाने वर्ग आप बंद के बजाय कारखाने विधि का उपयोग करना चाहते हैं:

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; 
    } 
} 

एक उदाहरण मॉडल आप सेवा प्रबंधक के माध्यम से दृष्टांत करने की कोशिश कर रहे हैं।

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. 
} 

अपने नियंत्रक में:

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

आप अपने मॉडल में SergiceManager/ServiceLocator इंजेक्षन सकता है, लेकिन फिर अपने मॉडल ServiceLocator पर निर्भर करेगा।

+2

बहुत उपयोगी जवाब! मॉडलमैनगर को मॉडल में इंजेक्ट करने का एक अन्य कारण इस प्रकार से हम अपने ऑब्जेक्ट को क्रमबद्ध नहीं कर सकते हैं (ServiceManager पर बंद होने के कारण)। और इसलिए हम सत्र पर मॉडल को सहेज नहीं सकते हैं। –

+1

एकमात्र चीज़ जोड़ी जाने की आवश्यकता है, मुझे लगता है कि आपको 'क्लोजर' का अधिक उपयोग नहीं करना चाहिए। इसके बजाए फैक्ट्री-क्लास लिखें। यह समग्र प्रदर्शन को बढ़ावा देगा, क्योंकि कक्षाएं केवल मांग पर तत्काल होंगी। सभी बंदरगाहों को प्रत्येक अनुरोध पर तत्काल किया जाएगा। – Sam

+1

एक और बात: यदि कुछ निर्भरताएं पूरी तरह से ** आवश्यक हैं ** इसे सेटर-इंजेक्शन – Sam