Search code examples
symfonyshopware6

Cannot autowire service AbstractController::setContainer() ContainerInterface does not exists


I'm currently trying to update my Shopware 6 plugin to Version 6.5. This new version update, increased the php and internal Symfony version. With this, I receive the following error when I try to initialize the plugin:

Cannot autowire service "**\Controller\*ProductController": argument "$container" of method
"Symfony\Bundle\FrameworkBundle\Controller\AbstractController::setContainer()" references
interface "Psr\Container\ContainerInterface" but no such service exists.
Available autowiring aliases for this interface are: "$parameterBag".

I use a abstract class for my controller:

use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

abstract class AMyController extends AbstractController
{

    public function __construct(private readonly SystemConfigService $systemConfigService)
    {
    }
//...
}

My controller:

use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Core\Framework\DataAbstractionLayer\Search\RequestCriteriaBuilder;
use Symfony\Component\Routing\Annotation\Route;

#[Route(defaults: ['_routeScope' => ['api']])]
class MyProductController extends AMyController 
{

    public function __construct(
        private readonly EntityRepository $orderRepository,
        private readonly EntityRepository $orderLineItemRepository,
        private readonly EntityRepository $productRepository,
        private readonly RequestCriteriaBuilder $requestCriteriaBuilder,
        private readonly SystemConfigService $systemConfigService
    )
    {
        parent::__construct($systemConfigService);
    }
//...
}

In my services.xml (Resources/config/services.xml) file I have this service registered like this:

    <services>
        <service
                id="Symfony\Component\DependencyInjection\ContainerInterface"
                alias="service_container"
        />

        <service id="MyPluginName\Controller\MyProductController" public="true">
            <argument type="service" id="order.repository"/>
            <argument type="service" id="order_line_item.repository"/>
            <argument type="service" id="product.repository"/>
            <argument type="service" id="Shopware\Core\Framework\DataAbstractionLayer\Search\RequestCriteriaBuilder"/>
            <argument type="service" id="Shopware\Core\System\SystemConfig\SystemConfigService"/>

            <call method="setContainer">
                <argument type="service" id="service_container"/>
            </call>
        </service>

composer.json

{
    "autoload": {
        "psr-4": {
            "MyPrefix\\MyPluginName\\": "src/"
        }
    },
    "require": {
        "shopware/core": ">=v6.5.0",
        "shopware/administration": ">=v6.5.0"
    }

}

Versions used:

  • Shopware 6.5.2.1
  • symfony 6.3.0
  • php 8.1.20

What I did so far:

  • I used the code refactor tool, and now use the Route Annotations #[Route(defaults: ['_routeScope' => ['api']])]
  • I used the services.xml file to manually define all services
  • Cleared cache with ./bin/console cache:clear

Solution

  • I was able to fix this behaviour by specifically loading the config file:

    class MyPlugin extends Plugin
    {
    
        public function build(ContainerBuilder $container): void
        {
            parent::build($container);
    
            $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/Core/Content/DependencyInjection'));
            $loader->load('controller.xml'); // same content as my services.xml
        }
    }
    

    It's important that the service definitions include the following tag:

    <service id="MyPluginName\Controller\MyProductController" public="true">
      <!-- all arguments ... -->
      <call method="setContainer">
         <argument type="service" id="service_container"/>
      </call>
    </service>
    

    The services.xml indeed wasn't loaded before.