Webador / SlmQueue

Laminas / Mezzio module that integrates with various queue management systems.
Other
137 stars 56 forks source link

JobPluginManager ServiceLocator only contains the job_manager Factories #146

Closed EMCP closed 9 years ago

EMCP commented 10 years ago

I'm trying to instantiate a Job with a dependency that resides in the General ZF2 Service Locator, but the ServiceLocator being passed into the Factory only contains the entries for slm_queue

How can i attain the overall superset of factories?

autoload/slm_queue.global.php

        'job_manager' => array(
            'factories' => array(
                'ServiceName\V1\Jobs\SubSet\ProcessJob' => 'ServiceName\V1\Jobs\Subset\ProcessJobFactory'
            )
        ),

ServiceController class

    public function __construct(ZFTableGateway $db_table,
                                QueueInterface $jobQueue,
                                JobPluginManager $jobPluginManager) {
        $this->db_table = $db_table;
        $this->jobQueue = $jobQueue;
        $this->jobPluginManager = $jobPluginManager;
    }

    protected function queuePostProcessing($result) {

        $newJob = $this->jobPluginManager->get('ServiceName\V1\Jobs\Subset\ProcessJob');

        $newJob->setContent( $result );

        $this->jobQueue->push($newJob);

        return true;
    }

ServiceControllerFactory class

    public function createService(ServiceLocatorInterface $services)
    {
        //Load all the Data Clients as a dependency
        $dependencyArray = array('dbDependency' => 'somedbdependency',
                                 'queueManagerDependency' => 'SlmQueue\Queue\QueuePluginManager',
                                 'jobPluginManagerDependency' => 'SlmQueue\Job\JobPluginManager');
        try {
            FactoryUtil::checkServicesDependencies($services, $dependencyArray, get_class($this));
        } catch (ServiceNotCreatedException $e) {
            // Already logged inside CheckServicesDependencies, you can attempt to recover or partially load here
            throw $e;
        }

        $dataTable = $dependencyArray['dbDependency'];

        $queueManagerDependency = $dependencyArray['queueManagerDependency'];
        $queueDependency = $queueManagerDependency->get('default');

        $jobPluginManagerDependency = $queueDependency->getJobPluginManager();

        return new ServiceInstance($dataTable, $queueDependency, $jobPluginManagerDependency) ;
    }
basz commented 10 years ago

In general Plugin Managers (such as the zf2 view plugin manager, controller plugin manager, but also the job manager) get the main service locator set when they are instantiated. The service locator passed to the createService method of a Factory is the actual plugin manager instance, but it has a method getServiceLocator that returns a reference to the main service locator. (plugin manager == service manager)

To inject to the merged config for example you could do something like this; ServiceName\V1\Jobs\Subset\ProcessJobFactory;

public function createService(ServiceLocatorInterface $locator)
{
    $sm      = $locator->getServiceManager();
    $config  = $sm->get('Config');

    $service = new \ServiceName\V1\Jobs\SubSet\ProcessJob($config);
}
EMCP commented 10 years ago

The Zend\ServiceManager\ServiceLocatorInterface inside Apigility aka ZF2 only has the following, but I will poke around further in an attempt to the get the overarching Factories.

/**
 * Service locator interface
 */
interface ServiceLocatorInterface
{
    /**
     * Retrieve a registered instance
     *
     * @param  string  $name
     * @throws Exception\ServiceNotFoundException
     * @return object|array
     */
    public function get($name);

    /**
     * Check for a registered instance
     *
     * @param  string|array  $name
     * @return bool
     */
    public function has($name);
}
basz commented 10 years ago

Yes but a concrete implementation of a AbstractPluginManager does have such a method.

Op 31 okt. 2014 om 18:26 heeft Erik notifications@github.com het volgende geschreven:

The Zend\ServiceManager\ServiceLocatorInterface inside Apigility only has the following

/**

  • Service locator interface / interface ServiceLocatorInterface { /*

    • Retrieve a registered instance
    • @param string $name
    • @throws Exception\ServiceNotFoundException
    • @return object|array */ public function get($name);

    /**

    • Check for a registered instance
    • @param string|array $name
    • @return bool */ public function has($name); }

— Reply to this email directly or view it on GitHub.

EMCP commented 9 years ago

Thank you, I was able to get the proper service manager as you described.

class ProcessJobFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $services)
    {

        if($services instanceof JobPluginManager){
            $mainServiceLocator = $services->getServiceLocator();
            $services = $mainServiceLocator;
        }

        //Load all the Data Clients as a dependency
        ...

        return new ProcessJob($dependency) ;
    }
}