Stoica Leonard
Stoica Leonard

Reputation: 41

ZF2 ServiceManager

I try to use ServiceManager from zf2 without MVC module. I have two file: classServiceManager.php and sm.php.

1) classServiceManager.php:

namespace ZF2;

use Zend\ServiceManager\ServiceManager; 
use Zend\ServiceManager\ServiceLocatorAwareInterface; 
use Zend\ServiceManager\ServiceLocatorInterface; 
use \InvalidArgumentException;  

class classServiceManager implements ServiceLocatorAwareInterface{
    protected $serviceLocator;

    function __construct(){
        //echo "SM: ". $this->getServiceLocator()->get('sm');
        echo "SM: ".$this->serviceLocator->get('sm');

    }

    function setServiceLocator(ServiceLocatorInterface $serviceLocator) {
        $this->serviceLocator = $serviceLocator;
      }

    function getServiceLocator() {
        return $this->serviceLocator;
    }       

}

2) sm.php

$config = array(...);

require_once 'Zend/Loader/AutoloaderFactory.php';
Zend\Loader\AutoloaderFactory::factory($config); 
......  
use ZF2\classServiceManager;

$serviceManager = new ServiceManager();
$serviceManager->setService('sm', 'aaa');   

$a = new classServiceManager();

But when I run sm.php, I get an error:

Fatal error: Call to a member function get() on a non-object....

Upvotes: 4

Views: 539

Answers (2)

JackLi
JackLi

Reputation: 139

By default, the Zend Framework MVC registers an initializer that will inject the ServiceManager instance, which is an implementation of Zend\ServiceManager\ServiceLocatorInterface, into any class implementing Zend\ServiceManager\ServiceLocatorAwareInterface.

so ServiceLocatorAwareInterface only used in MVC application.

if you want use ServiceManager from zf2 without MVC,you need create a ServiceManager by your self

this is mine

namespace Westdc\Service;

use Zend\ServiceManager\ServiceManager as Zend_ServiceManager;

class ServiceManager {

private $serviceManager;

function __construct()
{
    $this->serviceManager = new Zend_ServiceManager;
    $this->serviceManager->addAbstractFactory(new ServiceFactory);

    $configService = $this->serviceManager->get('ConfigService');
    $invoked_services = $configService->get('service.invoked.ini');

    foreach($invoked_services as $k=>$v) {
        $this->serviceManager->setInvokableClass($k, $v);
    }
}

public function addKey($key,$value = "")
{
    if(!empty($value))
        $this->serviceManager->$key($value);
    else
        $this->serviceManager->$key();
}

public function setServiceManager(Zend_ServiceManager $service)
{
    $this->serviceManager = $service;
}

public function getServiceManager()
{
    return $this->serviceManager;
}

} 

this is example when i use it

use Westdc\Service\ServiceManager;

$serviceManager = new ServiceManager();
$serviceManager = $serviceManager->getServiceManager();

$authService = $serviceManager->get('Auth');

Upvotes: 3

Sam
Sam

Reputation: 16455

Now I'm not too sure if my answer will be 100% correct, but you're doing a couple of weird things ;)

  1. don't name a class classServiceManager this is bound to create conflicts in understanding the code.
  2. Your classServiceManager doesn't magically get ZF2's ServiceManager injected. The Injection happens whenever a class is called FROM the ServiceManager.

So basically what you'd need to do is something like:

$originalSM = new ServiceManager();
$originalSM->setService('csm', 'ZF2\classServiceManager');

$a = $orignalSM->get('csm');

That way YOUR ServiceManager would be called from ZF2's ServiceManager and then your ServiceManager would know about ZF2's since it'll be injected.

HOWEVER: Your ServiceManager will not know about that at __construct(). The Injection happens via SetterInjection and therefore the Object has to be created first before a setter can be called.

My explanation may be a little weird but i hope u can make some use out of it.

Upvotes: 0

Related Questions