2013-02-16 53 views
9

पर नहीं है, तो मैं वास्तव में getServiceLocator का उपयोग करने के लिए कब और कब नहीं हूं इस पर उलझन में हूं। एक उदाहरण के रूप:ZF2 जब getServiceLocator() का उपयोग करना है और

+ Module 
-+ Helloworld 
--+ src 
---+ Controller 
----+ IndexController.php 
----+ IndexControllerFactory.php 

---+ Service 
----+ LogginService.php 
----+ GreetingService.php 
----+ GreetingServiceFactory.php 

GreetingServiceFactory.php सामग्री है:

<?php 
namespace Helloworld\Service; 

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


class GreetingServiceFactory implements FactoryInterface 
{ 

    public function createService (ServiceLocatorInterface $serviceLocator) 
    { 
     $greetingService = new GreetingService(); 

     $greetingService->setEventManager($serviceLocator->get('eventManager')); 

     $loggingService = $serviceLocator->get('loggingService'); 

     $greetingService->getEventManager()->attach('getGreeting', array(
      $loggingService, 
      'onGetGreeting' 
     )); 

     return $greetingService; 
    } 
} 

और IndexControllerFactory.php सामग्री है:

<?php 
namespace Helloworld\Controller; 

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

class IndexControllerFactory implements FactoryInterface 
{ 

    public function createService (ServiceLocatorInterface $serviceLocator) 
    { 
     $ctr = new IndexController(); 

     $ctr->setGreetingService($serviceLocator->getServiceLocator() 
      ->get('greetingService')); 
     return $ctr; 
    } 
} 

आप देख सकते हैं, मैं $ serviceLocator की जरूरत -> मेरे नियंत्रक फैक्टरी में getServiceLocator() प्राप्त करें, लेकिन मेरे सेवा कारखाने में नहीं। क्यूं कर? दोनों एक ही इंटरफ़ेस ServiceLocatorInterface का उपयोग करते हैं जो getServiceLocator() विधि को भी परिभाषित नहीं करता है।

module.config.php:

'controllers' => array(
    'factories' => array(
     'Helloworld\Controller\Index' => 'Helloworld\Controller\IndexControllerFactory' 
    ) 
) 
, 
'service_manager' => array(
    'invokables' => array(
     'loggingService' => 'Helloworld\Service\LoggingService' 
    ), 
    'factories' => array(
     'greetingService'=> 'Helloworld\Service\GreetingServiceFactory' 
    ), 
) 

मैं किसी भी स्पष्टीकरण :)

आपका दिन शुभ हो कि सराहना करेंगे!

उत्तर

20

विधि getServiceLocatorAbstractPluginManager पर परिभाषित किया गया है, क्योंकि यह ServiceLocatorAwareInterface लागू करता है। जैसा कि मैक्स 3 डब्ल्यू ने इंगित किया है, यह ServiceLocatorInterface का हिस्सा नहीं है, इसलिए सेवा कारखाने को लागू करते समय इसका उपयोग करने से बचें।

आप वैसे भी बंद के रूप में अपने कारखाने को परिभाषित करने और अभी भी इसका इस्तेमाल कर सकते हैं:

class MyModule 
{ 
    public function getControllerConfig() 
    { 
     return array(
      'factories' => array(
       'IndexController' => function (
        \Zend\ServiceManager\AbstractPluginManager $pm 
       ) { 
        $ctr = new IndexController(); 

        $ctr->setGreetingService(
         $pm 
          ->getServiceLocator() 
          ->get('greetingService') 
        ); 

        return $ctr; 
       }, 
      ), 
     ); 
    } 
} 

जबकि इस उदाहरण में $pm वास्तव में एक ServiceLocatorInterface उदाहरण है, तब भी आप "मुख्य" सेवा प्रबंधक के लिए एक संदर्भ पाने के लिए की आवश्यकता होगी 'greetingService' तक पहुंचने के लिए।

जेडएफ 2 नियंत्रकों, सेवाओं, सहायता सहायक, नियंत्रक प्लगइन्स इत्यादि के लिए विभिन्न सेवा प्रबंधकों या प्लगइन प्रबंधकों का उपयोग करता है ... यह मुख्य रूप से टाइप-संकेत के लिए है (AbstractPluginManager के इंटरफेस को समझने के लिए कि सख्तता कैसे प्राप्त की जाती है) और सुरक्षा के लिए।

इस मामले में, सुरक्षा समस्या उन सेवाओं तक पहुंच को अस्वीकार कर रही है जो नियंत्रक नहीं हैं, खासकर गतिशील controller पैरामीटर वाले मार्गों के साथ। यही कारण है कि नियंत्रकों को एक अलग प्लगइन प्रबंधक में रखा जाता है।

चूंकि नियंत्रक प्लगइन प्रबंधक "मुख्य" सेवा प्रबंधक से बनाया गया है, इसलिए इसे ServiceLocatorAwareInterface के लिए धन्यवाद भी शुरू किया गया है।

इस और अधिक स्पष्ट करने के लिए, मैं संबंधों का एक ग्राफ जोड़ दिया है (कारखाना शामिल नहीं है और यह के रूप में मान्य यूएमएल नहीं लेते हैं):

Pseudo-UML

+1

उस आरेख को बनाने के लिए आपने किस टूल का उपयोग किया था? सुंदर दिखाई देता है। – Leven

+1

@ लेवेन कि यूयूएमएल है – Ocramius

3

Denitively आप getServiceLocator का उपयोग shouln't के बाद से उस विधि ServiceLocatorInterface में निर्धारित नहीं है बजाय का उपयोग get()

5

आप कर सकते हैं के रूप में देखें, मुझे अपने कंट्रोलर फैक्ट्री में $ सेवा लोकेटर-> getServiceLocator() की आवश्यकता है, लेकिन मेरे सेवा फैक्टरी में नहीं। क्यूं कर?

नियंत्रक फैक्ट्री को एक अलग सेवा प्रबंधक उदाहरण ("नियंत्रक लोडर") द्वारा मुख्य रूप से बुलाया जाता है। ऐसा इसलिए है कि प्रेषक मुख्य सेवा प्रबंधक द्वारा तत्काल कक्षा में एक मनमाना वर्ग का परिणाम नहीं दे सकता है।

नतीजतन, नियंत्रक फैक्ट्री की $ सेवा लोकेटर आपको वह नहीं है जब आप 'ग्रीटिंग सेवा' को पुनर्प्राप्त करना चाहते हैं, क्योंकि 'ग्रीटिंग सेवा' मुख्य सेवा प्रबंधक के साथ पंजीकृत है। नियंत्रक से मुख्य सर्वर मैनेजर प्राप्त करने के लिए, आप getServiceLocator() का उपयोग करते हैं और अब आपके पास मुख्य सेवा प्रबंधक का उदाहरण है() 'ग्रीटिंग सेवा'

इसे 'peering' के रूप में जाना जाता है। यानी "नियंत्रक लोडर" सेवा प्रबंधक (कॉन्फ़िगरेशन में 'नियंत्रकों' कुंजी के माध्यम से कॉन्फ़िगर किया गया है या मॉड्यूल क्लास में getController कॉन्फ़िगरेशन() प्राप्त किया गया है) मुख्य सेवा प्रबंधक के साथ एक सहकर्मी के रूप में स्थापित किया गया है।

0

मैं इस एक विकल्प के आधार module.config.php सेटअप

अब मैं कुछ इसी तरह कर रहा था लेकिन कुछ इस तरह का उपयोग कर का उपयोग करता है के रूप में की पेशकश कर रहा हूँ।

class BaseServices extends AbstractActionController 
implements ServiceLocatorAwareInterface{ 
    ... 
    public function setServiceLocator(ServiceLocatorInterface $serviceLocator){ 
     if($serviceLocator instanceof ControllerManager){ 
      $this->service_locator = $serviceLocator->getServiceLocator(); 

      $this->entities_service = $this->service_locator 
      ->get('entities_service'); 

      $this->session = new Session(array(
      'entities_service'=>$this->entities_service, 
      'service_locator'=>$this->service_locator, 
     )); 
      return $this; 
     } 
     } 
    } 
... 
} 

अब बात यह है कि स्टम्प्ड था मुझे अहसास है कि मैं केवल पहले सेवा लोकेटर है कि किसी भी नियंत्रक कि इस वर्ग फैली इन्स्टेन्शियशन दौरान प्रयोग किया जाता है का उपयोग करने के लिए आवश्यक करने के लिए आने के लिए हो रही थी ...

तात्कालिकता पर: इस कक्षा को पहले नियंत्रक प्रबंधक और फिर सेवा प्रबंधक को setServiceLocator विधि के लिए खिलाया जा रहा था।

मैं केवल नियंत्रक प्रबंधक और सेवा प्रबंधक को अपने कारखानों को तुरंत चालू करने के लिए इसकी विधि का उपयोग करना चाहता था;

मेरी module.config.php पर आंशिक

अब मैं की तरह कुछ के लिए इस्तेमाल किया जा सकता था सही ServiceLocator के लिए फिल्टर करने के लिए ... फिर भी मैं रूप में छोटे रूप बायलर प्लेट का उपयोग करने का एक प्रशंसक हूँ निम्नलिखित आवश्यक ...

interface AbstractFactoryInterface 
{ 
    public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName); 

    public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName); 
} 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^