Container Dependecy Injection not working in Fixtu

2019-06-05 07:59发布

问题:

I upgraded a project from Symfony 2.0 to 2.1. After that my tests stopped working. The problem is that I use fixtures which implement the ContainerAware interface. Now after the upgrade the setContainer() method does not get called anymore. I tried upgrading further to 2.2. The problem still persists.

composer.json:

{
"name": "symfony/framework-standard-edition",
"license": "MIT",
"type": "project",
"description": "The \"Symfony Standard Edition\" distribution",
"autoload": {
    "psr-0": { "": "src/" }
},
"require": {
    "php": ">=5.3.3",
    "symfony/symfony": "2.2.*",
    "doctrine/orm": ">=2.2.3,<2.5-dev",
    "doctrine/doctrine-bundle": "1.2.*",
    "twig/extensions": "1.0.*@dev",
    "symfony/assetic-bundle": "2.1.*",
    "symfony/swiftmailer-bundle": "2.2.*",
    "symfony/monolog-bundle": "2.2.*",
    "sensio/distribution-bundle": "2.2.*",
    "sensio/framework-extra-bundle": "2.2.*",
    "sensio/generator-bundle": "2.2.*",
    "jms/security-extra-bundle": "1.4.*",
    "jms/di-extra-bundle": "1.3.*",
    "kriswallsmith/assetic": "1.1.*@dev",
"knplabs/knp-menu-bundle":"dev-master",
"knplabs/knp-menu":"dev-master",
    "doctrine/doctrine-fixtures-bundle": "dev-master",
    "doctrine/data-fixtures": "1.0.*@ALPHA",
"doctrine/migrations": "dev-master",
"doctrine/doctrine-migrations-bundle": "dev-master",
    "jms/translation-bundle": "dev-master"


},
"scripts": {
    "post-install-cmd": [
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"
    ],
    "post-update-cmd": [
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
        "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"
    ]
},
"extra": {
    "symfony-app-dir": "app",
    "symfony-web-dir": "web",
    "branch-alias": {
        "dev-master": "2.2-dev"
    }
}

}

and my fixture looks like this:

LoadUserData.php

<?php
namespace FINDOLOGIC\CustomerLoginBundle\DataFixtures\ORM;

use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;


class LoadUserData implements FixtureInterface, ContainerAwareInterface
{
    /**
     * @var ContainerInterface
     */
    private $container;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    public function load(ObjectManager $manager)
    {
     [...]
    }
}

I've already taken a look at Doctrine fixtures not working after updating to Symfony 2.1.8 but it does not solve my problem.

I'm really looking forward to your input as I have been trying to solve this for quite a while now.

回答1:

I had exactly the same issue, nothing would fix it via changing round composer order, order in the kernal, extending or implementing etc, so in the end, I just pass the container in from the test:

public function testLogin()
{

///
$fixture = new UserFixtures();
$fixture->setContainer($container);
///

$executor->execute($loader->getFixtures(), true);

And now it works fine.



回答2:

Solution:

Make sure you not only implement ContainerAwareInterface - you should extend ContainerAware

use Symfony\Component\DependencyInjection\ContainerAware;

// ContainerAware... already implements ContainerAwareInterface

class YourFixture extends ContainerAware 
{
    // ...

Another suggestion:

Move Datafixtures further up in your composer.json ( before doctrine/orm ) to have composer generate the classmap correctly.

The 2.0 documentation states.

Be sure to register the new namespace before Doctrine\Common. Otherwise, Symfony will look for data fixture classes inside the Doctrine\Common directory. Symfony's autoloader always looks for a class inside the directory of the first matching namespace, so more specific namespaces should always come first.

Furthermore you don't need fixtures-bundle and fixtures as fixtures is a dependency of fixtures-bundle.

Hope that helps.