Philip Gerlach
Philip Gerlach

Reputation: 13

Symfony2 Dependency Injection with parent services does not work

I'm currently trying configure my Symfony Dependency Injection so that I'm able to use parent services. Following the description I found in http://symfony.com/doc/current/components/dependency_injection/parentservices.html I tried to set up the following classes as a first test:

Mailer.php:

namespace testing;

class Mailer
{
    private $transport;

    public function __construct($transport) {
        $this->transport = $transport;
    }

    public function getTransport() {
        return $this->transport;
    }
}

MailManager.php:

namespace testing;

abstract class MailManager
{
    protected $mailer;

    public function setMailer(Mailer $mailer)
    {
         $this->mailer = $mailer;
    }
}

NewsletterManager.php:

namespace testing;

class NewsletterManager extends MailManager {
    function getTransport() {
        return $this->mailer->getTransport();
    }
}

services.yml:

 parameters:
    mailer.transport: sendmail

services:
    mailer:
        class:     testing\Mailer
        arguments: [%mailer.transport%]
    mail_manager:
        class:     testing\MailManager
        abstract:  true
        calls:
             - [ setMailer, [ @mailer ] ]
    newsletter_manager:
        class:     testing\NewsletterManager
        parent:    mail_manager

But when I try to run this configuration with the following code:

require_once 'ClassLoading.php';
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/config'));
$loader->load('services.yml');

$nm = $container->get('newsletter_manager');
echo $nm->getTransport();

I always get this error:

PHP Fatal error:  Call to a member function getTransport() on a non-object in C:\IGMI\workspace\TryingHard\loading\NewsletterManager.php on line 7

The one thing seems to be that the setter of the abstract class is never called, but even if I make the abstract class concrete and retrieve it from the container with the setter actually being called, this doesn't solve the problem of the mailer object being not set. So it appeards to me that there is also a problem with the establishing of the subclass relationship.

Any help would be appreciated!

Upvotes: 1

Views: 5397

Answers (1)

l3l0
l3l0

Reputation: 3393

You should compile container builder before try access services I think... so it should looks like:

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/config'));
$loader->load('services.yml');

$container->compile(); //add this line

$nm = $container->get('newsletter_manager');
echo $nm->getTransport();

Upvotes: 4

Related Questions