Symfony injects a string instead of service

196 views Asked by At

I have this Symfony 5.1 app where I'm trying to inject a custom cache adapter implementation but instead it injects a string t72YSNXSq7.

Here is my configuration:

cache.yaml

framework:
    cache:
        pools:
            stories:
                name: cache.stories
                adapter: Rikudou\DynamoDbCacheBundle\Cache\DynamoDbCacheAdapter

The bundle configuration (two files) is as follows (and it works in other Symfony apps):

services:
  rikudou.dynamo_cache.cache: # arguments defined in extension
    class: Rikudou\DynamoDbCache\DynamoDbCache
    arguments:
      $clock: ~
      $converter: '@rikudou.dynamo_cache.converter_registry'

  rikudou.dynamo_cache.adapter:
    class: Rikudou\DynamoDbCacheBundle\Cache\DynamoDbCacheAdapter
    arguments:
      - '@rikudou.dynamo_cache.cache'
services:
  Rikudou\DynamoDbCacheBundle\Cache\DynamoDbCacheAdapter: '@rikudou.dynamo_cache.adapter'
  Rikudou\DynamoDbCache\DynamoDbCache: '@rikudou.dynamo_cache.cache'

My app services.yaml (the relevant part):

services:
    _instanceof:
        App\DependencyInjection\StoriesCacheInterface:
            tags:
                - app.stories_cache

Then I have this compiler pass which uses the cache.stories service for services tagged with app.stories_cache, e.g. those implementing App\DependencyInjection\StoriesCacheInterface:

    public function process(ContainerBuilder $container): void
    {
        $services = array_keys($container->findTaggedServiceIds('app.stories_cache'));
        foreach ($services as $service) {
            $service = $container->getDefinition($service);
            $reflection = new ReflectionClass($service->getClass());
            $constructor = $reflection->getConstructor();
            if ($constructor === null) {
                continue;
            }
            $arguments = $constructor->getParameters();
            foreach ($arguments as $argument) {
                if (!($type = $argument->getType())) {
                    continue;
                }
                if ((string) $type !== AdapterInterface::class) {
                    continue;
                }
                $service->setArgument('$' . $argument->getName(), new Reference('cache.stories'));
            }
        }
    }

And finally, this is the generated container file, which injects t72YSNXSq7 instead of an instance of Rikudou\DynamoDbCache\DynamoDbCache (indented for better readability):

        return $container->services['App\\Controller\\AuthorController'] = new \App\Controller\AuthorController(
            new \App\Service\AuthorReader(
                (
                    $container->privates['cache.stories'] ?? (
                        $container->privates['cache.stories'] = new \Rikudou\DynamoDbCacheBundle\Cache\DynamoDbCacheAdapter('t72YSNXSq7') // the wrong line
                    )
                ),
                ($container->privates['App\\Service\\StorySearcher'] ?? $container->load('getStorySearcherService')), 
                ($container->privates['App\\Service\\Downloader'] ?? ($container->privates['App\\Service\\Downloader'] = new \App\Service\Downloader()))),
            $a
        );
0

There are 0 answers