familymangreg
familymangreg

Reputation: 1282

ZF2 - ServiceManager and 'aware' interfaces

First ZF2 application, getting there, but I think still missing a think or two when it comes to dependency injection and the ServiceManager.

I have a particular problem at the moment with a new database gateway class I'm writing. I won't to inject a database adapter, so I've implemented AdapterAwareInterface. But the setDbAdapter method is never called in my class. I'm wondering if someone would be so kind as to look at my code and suggest what might be going wrong (or what I'm missing!).

So, here is the class in which I implement AdapterAwareInterface.

<?php
namespace Foo\Database;
use Zend\Db\Adapter\Adapter;
use Zend\Db\Adapter\AdapterAwareInterface;
use Zend\Log\LoggerAwareInterface;
use Zend\Log\LoggerInterface;


class Gateway implements AdapterAwareInterface, LoggerAwareInterface
{
protected $logger = NULL;
protected $db = NULL;

public function setDbAdapter(Adapter $adapter)
{
    $this->db = $adapter;
} 

public function setLogger(LoggerInterface $logger)
{
    $this->logger = $logger;
}

This is an extract from my module file showing how I configure my service manager:

    public function getServiceConfig()
{
    return array(
        'factories' => array(
          ....
        ),
        'invokables' => array(
            'FooDatabaseGateway' => 'Foo\Database\Gateway',
        ),
        'abstract_factories' => array(
            'AbstractFeedParserFactory' => 'Bookmakers\Odds\Feeds\AbstractFeedParserFactory',
        ),
    );
}

This is how I'm testing:

gateway = $this->getServiceLocator()->get('FooDatabaseGateway');

And this is part of my global config:

return array(
  'db' => array(
    'driver'         => 'Pdo',
    'dsn'            => 'mysql:dbname=kickoff_manager;host=localhost',
    'username'       => '****',
    'password'       => '****',
    'driver_options' => array(
    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
  ),
  ),
  'service_manager' => array(
  'factories' => array(
      'Zend\Db\Adapter\Adapter'
              => 'Zend\Db\Adapter\AdapterServiceFactory',
  ),
),
);

Many thanks for any help you can provide.

:wq

Upvotes: 2

Views: 3030

Answers (1)

familymangreg
familymangreg

Reputation: 1282

OK a fresh pair of eyes on this problem this morning. I think this is the write answer.. At least that is to say its working for me. If anyone wants to suggest an entirely different of better approach, then please do so :-).

So the bit is was missing was to use an initializer in my service manager config to call the setDbAdapter function on any class instances that implement AdapterAwareInterface. So in the array I return from getServiceConfig in my Module.php file, I have added the following entry:

public function getServiceConfig() {
  return array(
    'initializers' => array(
      'db' => function($service, $sm)
      {
        if ($service instanceof AdapterAwareInterface)
        {
          $service->setDbAdapter($sm->get('Zend\Db\Adapter\Adapter'));
        }
      }....

I think what I'm missing while learning ZF2 is that there are a lot of building blocks to work with, but you've got to put a lot of them together yourself.

Things are looking good and I'm enjoying the Framework, but there is a lot to learn, and I'm still not convinced by using Server Manager injection rather than good old constructor injection!

:wq

Upvotes: 3

Related Questions