0

Upgraded a Symfony project from v 4 to v6.3 and my autowiring is no longer working, it seems that the services.yaml is being ignored but cannot figure out why.

<?php

namespace Api;

use App\DependencyInjection\AppExtension;
use Api\EventListener\ExceptionSubscriber;
use Api\EventListener\MonitoringSubscriber;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\HttpKernel\Kernel as SymfonyKernel;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;

/**
 * @property ContainerInterface $container
 */
class Kernel extends SymfonyKernel
{
    use MicroKernelTrait;

    private const ALLOWED_CONFIG_EXTENSIONS = '.{php,yaml}';
    private const CONFIG_DIR = 'config';
    private const DEFAULT_CACHE_PATH = '/tmp';
    private const DEFAULT_LOG_PATH = '/tmp';
    private ?string $rootProjectDir = null;

    /**
     * @inheritdoc
     */
    public function registerBundles(): iterable
    {
        $path = $this->getRootProjectDir() . DIRECTORY_SEPARATOR . self::CONFIG_DIR . '/bundles.php';
        $contents = file_exists($path) ? require $path : [];

        $contents = array_merge([
            FrameworkBundle::class => ['all' => true],
        ], $contents);

        foreach ($contents as $class => $envs) {
            if (isset($envs['all']) || isset($envs[(string)$this->environment])) {
                yield new $class();
            }
        }
    }

    /**
     * @return string
     */
    public function getLogDir(): string
    {
        return $_SERVER['LOG_DIR'] ?? self::DEFAULT_LOG_PATH;
    }

    /**
     * @return string
     */
    public function getCacheDir(): string
    {
        return $_SERVER['CACHE_DIR'] ?? self::DEFAULT_CACHE_PATH;
    }
    
    private function configureContainer(
        ContainerConfigurator $container,
        LoaderInterface $loader,
        ContainerBuilder $builder
    ): void {
        $configDir = $this->getConfigDir();

        $container->services()->defaults()->autowire()->autoconfigure();

        $container->import($configDir.'/{packages}/*.{php,yaml}');
        $container->import($configDir.'/{packages}/'.$this->environment.'/*.{php,yaml}');

        if (is_file($configDir.'/services.yaml')) {
            $container->import($configDir.'/services.yaml');
            $container->import($configDir.'/{services}_'.$this->environment.'.yaml');
        } else {
            $container->import($configDir.'/{services}.php');
        }

        $container->services()->set(ExceptionSubscriber::class)->tag('kernel.event_subscriber');
        $container->services()->set(MonitoringSubscriber::class)->tag('kernel.event_subscriber');
    }

    protected function configureRoutes(RoutingConfigurator $routes): void
    {
        $dir = $this->getRootProjectDir() . DIRECTORY_SEPARATOR . self::CONFIG_DIR;

        $routes->import($dir. '/{routes}/*' . self::ALLOWED_CONFIG_EXTENSIONS);
        $routes->import($dir. '/{routes}' . self::ALLOWED_CONFIG_EXTENSIONS);
    }

    /**
     * This method is similar to `getProjectDir` accept that it allows for being a vendor package
     *
     * @return string
     */
    private function getRootProjectDir(): string
    {
        if (null === $this->rootProjectDir) {
            $project = $this->getProjectDir();

            return $this->rootProjectDir = 'vendor' === substr(\dirname($project, 2), -6)
                ? \dirname($project, 3)
                : $project;
        }

        return $this->rootProjectDir;
    }
}

This is my Kernel and my services.yaml

services:
  # default configuration for services in *this* file
  _defaults:
    autowire: true      # Automatically injects dependencies in your services.
    autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
    public: false       # Allows optimizing the container by removing unused services; this also means
      # fetching services directly from the container via $container->get() won't work.
    # The best practice is to be explicit about your dependencies anyway.

 Hermes\:
    resource: '../src/*'

# Hermes\Controllers\:
#    resource: '../src/Controllers'
#    tags: ['controller.service_arguments']

 Sparrow\Sparrow:
    public: true

  CacheAdapters\CacheAdapterInterface:
    arguments:
      $driver: 'memcached'
      $config:
        connection:
          host: '127.0.0.1'
          port: '11211'
    factory: ['CacheAdapters\CacheAdapterFactory', get]

 Hermes\Service\Cache\CacheService:
    arguments:
      $cacheConfig:
        adapter: 'memcached'
        connection:
          host: '127.0.0.1'
          port: '11211'

 Hermes\Database\Connection:
    class:Hermes\Database\Connection
    factory: ['Hermes\Database\ConnectionFactory', 'createConnection']
    arguments:
      $config:
        type: mysql
        host: mysql.local
        dbname: HERMES
        user: root
        password:
        port: 3306
        persistent: true

 Hermes\Database\Manager:
    class:Hermes\Database\Manager
    factory: ['Hermes\Database\DatabaseManagerFactory', 'createDatabaseManager']
    arguments:
      $config:
        type: mysql
        host: mysql.local
        dbname: HERMES
        user: root
        password:
        port: 3306
        persistent: true

 Hermes\ObjectMapping\RepositoryManager:
    class:Hermes\ObjectMapping\RepositoryManager
    factory: ['Hermes\ObjectMapping\RepositoryManagerFactory', 'createRepositoryManager']

  Logger\LoggerInterface:
    class: Logger\LoggerInterface
    arguments: ['%service.logger%']
    factory: ['Logger\LoggerFactory', get]
    public: true

I've tried every possible combination I can see on the web but still unable to see what I'm missing, important to note this was working before I did the upgrade, is there somewhere new I need to register to get the autowiring of my services to work again?

André Figueira
  • 6,048
  • 14
  • 48
  • 62
  • It is hard to say but maybe start with the default S6 Kernel.php just to get something working and then customize any methods that need it. The code for loading services.yaml has changed multiple times over the versions. – Cerad Sep 01 '23 at 16:53

0 Answers0