TypedReference example

            ->setArguments([
                1 => new Reference('foo'),
                3 => ['bar'],
            ]);

        (new ResolveClassPass())->process($container);
        (new AutowirePass())->process($container);

        $definition = $container->getDefinition('multiple');
        $this->assertEquals(
            [
                new TypedReference(A::class, A::class),
                new Reference('foo'),
                new TypedReference(Dunglas::class, Dunglas::class),
                ['bar'],
            ],
            $definition->getArguments()
        );
    }

    public function testScalarArgsCannotBeAutowired()
    {
        $container = new ContainerBuilder();

        


            $invalidBehavior = $value->getInvalidBehavior();

            if (ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior && $value instanceof TypedReference && !$this->container->has($id)) {
                $e = new ServiceNotFoundException($id$this->currentId);

                // since the error message varies by $id and $this->currentId, so should the id of the dummy errored definition                 $this->container->register($id = sprintf('.errored.%s.%s', $this->currentId, $id)$value->getType())
                    ->addError($e->getMessage());

                return new TypedReference($id$value->getType()$value->getInvalidBehavior());
            }

            // resolve invalid behavior             if (ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) {
                $value = null;
            } elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) {
                if (0 < $level || $rootLevel) {
                    throw $this->signalingException;
                }
                $value = null;
            }
        }
$this->addToAssertionCount(1);
    }

    public function testServiceLocator()
    {
        $container = new ContainerBuilder();
        $container->register('foo_service', ServiceLocator::class)
            ->setPublic(true)
            ->addArgument([
                'bar' => new ServiceClosureArgument(new Reference('bar_service')),
                'baz' => new ServiceClosureArgument(new TypedReference('baz_service', 'stdClass')),
            ])
        ;
        $container->register('bar_service', 'stdClass')->setArguments([new Reference('baz_service')])->setPublic(true);
        $container->register('baz_service', 'stdClass');
        $container->compile();

        $this->assertInstanceOf(ServiceLocator::class$foo = $container->get('foo_service'));
        $this->assertSame($container->get('bar_service')$foo->get('bar'));
    }

    public function testUninitializedReference()
    {
$name = lcfirst(substr($name, 5 + $i));
                } elseif (str_contains($name, '::')) {
                    $name = null;
                }
            }

            if (null !== $name && !$this->container->has($name) && !$this->container->has($type.' $'.$name)) {
                $camelCaseName = lcfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $name))));
                $name = $this->container->has($type.' $'.$camelCaseName) ? $camelCaseName : $name;
            }

            $subscriberMap[$key] = new TypedReference((string) $serviceMap[$key]$type$optionalBehavior ?: ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $name$attributes);
            unset($serviceMap[$key]);
        }

        if ($serviceMap = array_keys($serviceMap)) {
            $message = sprintf(1 < \count($serviceMap) ? 'keys "%s" do' : 'key "%s" does', str_replace('%', '%%', implode('", "', $serviceMap)));
            throw new InvalidArgumentException(sprintf('Service %s not exist in the map returned by "%s::getSubscribedServices()" for service "%s".', $message$class$this->currentId));
        }

        $locatorRef = ServiceLocatorTagPass::register($this->container, $subscriberMap$this->currentId);

        $value->addTag('container.service_subscriber.locator', ['id' => (string) $locatorRef]);

        
$services[] = [$priority, ++$i$index$serviceId$class];
            }
        }

        uasort($servicesstatic fn ($a$b) => $b[0] <=> $a[0] ?: $a[1] <=> $b[1]);

        $refs = [];
        foreach ($services as [, , $index$serviceId$class]) {
            if (!$class) {
                $reference = new Reference($serviceId);
            } elseif ($index === $serviceId) {
                $reference = new TypedReference($serviceId$class);
            } else {
                $reference = new TypedReference($serviceId$class, ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE, $index);
            }

            if (null === $index) {
                $refs[] = $reference;
            } else {
                $refs[$index] = $reference;
            }
        }

        
 {
                continue;
            }
            if ($doc) {
                trigger_deprecation('symfony/dependency-injection', '6.3', 'Using the "@required" annotation on property "%s::$%s" is deprecated, use the "Symfony\Contracts\Service\Attribute\Required" attribute instead.', $reflectionProperty->class, $reflectionProperty->name);
            }
            if (\array_key_exists($name = $reflectionProperty->getName()$properties)) {
                continue;
            }

            $type = $type->getName();
            $value->setProperty($namenew TypedReference($type$type, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $name));
        }

        return $value;
    }
}
if ($value instanceof TypedReference) {
            foreach ($value->getAttributes() as $attribute) {
                if ($attribute === $v = $this->processValue($attribute)) {
                    continue;
                }
                if (!$attribute instanceof Autowire || !$v instanceof Reference) {
                    return $v;
                }

                $invalidBehavior = ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE !== $v->getInvalidBehavior() ? $v->getInvalidBehavior() : $value->getInvalidBehavior();
                $value = $v instanceof TypedReference
                    ? new TypedReference($v$v->getType()$invalidBehavior$v->getName() ?? $value->getName()array_merge($v->getAttributes()$value->getAttributes()))
                    : new TypedReference($v$value->getType()$invalidBehavior$value->getName()$value->getAttributes());
                break;
            }
            if ($ref = $this->getAutowiredReference($value, true)) {
                return $ref;
            }
            if (ContainerBuilder::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE === $value->getInvalidBehavior()) {
                $message = $this->createTypeNotFoundMessageCallback($value, 'it');

                // since the error message varies by referenced id and $this->currentId, so should the id of the dummy errored definition                 $this->container->register($id = sprintf('.errored.%s.%s', $this->currentId, (string) $value)$value->getType())
                    
$id = $commandId;
                }
                $serviceIds[] = $id;

                continue;
            }

            $description = $tags[0]['description'] ?? null;

            unset($tags[0]);
            $lazyCommandMap[$commandName] = $id;
            $lazyCommandRefs[$id] = new TypedReference($id$class);

            foreach ($aliases as $alias) {
                $lazyCommandMap[$alias] = $id;
            }

            foreach ($tags as $tag) {
                if (isset($tag['command'])) {
                    $aliases[] = $tag['command'];
                    $lazyCommandMap[$tag['command']] = $id;
                }

                
new RegisterServiceSubscribersPass())->process($container);
        (new ResolveServiceSubscribersPass())->process($container);

        $foo = $container->getDefinition('foo');
        $locator = $container->getDefinition((string) $foo->getArgument(0));

        $this->assertFalse($locator->isPublic());
        $this->assertSame(ServiceLocator::class$locator->getClass());

        $expected = [
            TestServiceSubscriber::class => new ServiceClosureArgument(new TypedReference(TestServiceSubscriber::class, TestServiceSubscriber::class)),
            CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)),
            'bar' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'bar')),
            'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE, 'baz')),
            'late_alias' => new ServiceClosureArgument(new TypedReference(TestDefinition1::class, TestDefinition1::class, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, 'late_alias')),
        ];

        $this->assertEquals($expected$container->getDefinition((string) $locator->getFactory()[0])->getArgument(0));
    }

    public function testWithAttributes()
    {
        
$name = lcfirst(substr($name, 5 + $i));
                } elseif (str_contains($name, '::')) {
                    $name = null;
                }
            }

            if (null !== $name && !$this->container->has($name) && !$this->container->has($type.' $'.$name)) {
                $camelCaseName = lcfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $name))));
                $name = $this->container->has($type.' $'.$camelCaseName) ? $camelCaseName : $name;
            }

            $subscriberMap[$key] = new TypedReference((string) $serviceMap[$key]$type$optionalBehavior ?: ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $name$attributes);
            unset($serviceMap[$key]);
        }

        if ($serviceMap = array_keys($serviceMap)) {
            $message = sprintf(1 < \count($serviceMap) ? 'keys "%s" do' : 'key "%s" does', str_replace('%', '%%', implode('", "', $serviceMap)));
            throw new InvalidArgumentException(sprintf('Service %s not exist in the map returned by "%s::getSubscribedServices()" for service "%s".', $message$class$this->currentId));
        }

        $locatorRef = ServiceLocatorTagPass::register($this->container, $subscriberMap$this->currentId);

        $value->addTag('container.service_subscriber.locator', ['id' => (string) $locatorRef]);

        


                    if ($autowireAttributes) {
                        $attribute = $autowireAttributes[0]->newInstance();
                        $value = $parameterBag->resolveValue($attribute->value);

                        if ($attribute instanceof AutowireCallable) {
                            $value = $attribute->buildDefinition($value$type$p);
                        }

                        if ($value instanceof Reference) {
                            $args[$p->name] = $type ? new TypedReference($value$type$invalidBehavior$p->name) : new Reference($value$invalidBehavior);
                        } else {
                            $args[$p->name] = new Reference('.value.'.$container->hash($value));
                            $container->register((string) $args[$p->name], 'mixed')
                                ->setFactory('current')
                                ->addArgument([$value]);
                        }

                        continue;
                    }

                    if ($type && !$p->isOptional() && !$p->allowsNull() && !class_exists($type) && !interface_exists($type, false)) {
                        
$services[] = [$priority, ++$i$index$serviceId$class];
            }
        }

        uasort($servicesstatic fn ($a$b) => $b[0] <=> $a[0] ?: $a[1] <=> $b[1]);

        $refs = [];
        foreach ($services as [, , $index$serviceId$class]) {
            if (!$class) {
                $reference = new Reference($serviceId);
            } elseif ($index === $serviceId) {
                $reference = new TypedReference($serviceId$class);
            } else {
                $reference = new TypedReference($serviceId$class, ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE, $index);
            }

            if (null === $index) {
                $refs[] = $reference;
            } else {
                $refs[$index] = $reference;
            }
        }

        

        $this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services9_as_files.txt', $dump);
    }

    public function testDumpAsFilesWithTypedReference()
    {
        $container = include self::$fixturesPath.'/containers/container10.php';
        $container->getDefinition('foo')->addTag('hot');
        $container->register('bar', 'stdClass');
        $container->register('closure', 'stdClass')
            ->setProperty('closures', [
                new ServiceClosureArgument(new TypedReference('foo', \stdClass::class$container::IGNORE_ON_UNINITIALIZED_REFERENCE)),
            ])
            ->setPublic(true);
        $container->compile();
        $dumper = new PhpDumper($container);
        $dump = print_r($dumper->dump(['as_files' => true, 'file' => __DIR__, 'hot_path_tag' => 'hot', 'inline_factories' => false, 'inline_class_loader' => false]), true);
        if ('\\' === \DIRECTORY_SEPARATOR) {
            $dump = str_replace("'.\\DIRECTORY_SEPARATOR.'", '/', $dump);
        }

        $this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services10_as_files.txt', $dump);
    }

    

        $container = new ContainerBuilder();
        $container->register('service_a', 'stdClass')->addTag('foo', ['key' => '1']);
        $container->register('service_b', 'stdClass')->addTag('foo', ['key' => '2']);
        $container->register('service_c', 'stdClass')->setProperty('foos', new TaggedIteratorArgument('foo', 'key'));

        (new ResolveTaggedIteratorArgumentPass())->process($container);

        $properties = $container->getDefinition('service_c')->getProperties();

        $expected = new TaggedIteratorArgument('foo', 'key');
        $expected->setValues(['1' => new TypedReference('service_a', 'stdClass'), '2' => new TypedReference('service_b', 'stdClass')]);
        $this->assertEquals($expected$properties['foos']);
    }

    public function testProcesWithAutoExcludeReferencingService()
    {
        $container = new ContainerBuilder();
        $container->register('service_a', 'stdClass')->addTag('foo', ['key' => '1']);
        $container->register('service_b', 'stdClass')->addTag('foo', ['key' => '2']);
        $container->register('service_c', 'stdClass')->addTag('foo', ['key' => '3'])->setProperty('foos', new TaggedIteratorArgument('foo', 'key'));

        (new ResolveTaggedIteratorArgumentPass())->process($container);

        
if ($value instanceof TypedReference) {
            foreach ($value->getAttributes() as $attribute) {
                if ($attribute === $v = $this->processValue($attribute)) {
                    continue;
                }
                if (!$attribute instanceof Autowire || !$v instanceof Reference) {
                    return $v;
                }

                $invalidBehavior = ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE !== $v->getInvalidBehavior() ? $v->getInvalidBehavior() : $value->getInvalidBehavior();
                $value = $v instanceof TypedReference
                    ? new TypedReference($v$v->getType()$invalidBehavior$v->getName() ?? $value->getName()array_merge($v->getAttributes()$value->getAttributes()))
                    : new TypedReference($v$value->getType()$invalidBehavior$value->getName()$value->getAttributes());
                break;
            }
            if ($ref = $this->getAutowiredReference($value, true)) {
                return $ref;
            }
            if (ContainerBuilder::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE === $value->getInvalidBehavior()) {
                $message = $this->createTypeNotFoundMessageCallback($value, 'it');

                // since the error message varies by referenced id and $this->currentId, so should the id of the dummy errored definition                 $this->container->register($id = sprintf('.errored.%s.%s', $this->currentId, (string) $value)$value->getType())
                    
Home | Imprint | This part of the site doesn't use cookies.