Repository: symfony/symfony
File: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php (PHP)

Code before:
        if ($this->readConfigEnabled('http_client.retry_failed', $container, $retryOptions)) {
            $this->registerRetryableHttpClient($retryOptions, 'http_client', $container);
        }

        if (ContainerBuilder::willBeAvailable('guzzlehttp/uri-template', \GuzzleHttp\UriTemplate\UriTemplate::class, [])) {
            $container->setAlias('http_client.uri_template_expander', 'http_client.uri_template_expander.guzzle');
        } elseif (ContainerBuilder::willBeAvailable('rize/uri-template', \Rize\UriTemplate::class, [])) {
            $container->setAlias('http_client.uri_template_expander', 'http_client.uri_template_expander.rize');
        }

        $container
            ->getDefinition('http_client.uri_template')
            ->setArgument(2, $defaultUriTemplateVars);

        foreach ($config['scoped_clients'] as $name => $scopeConfig) {
            if ($container->has($name)) {
                throw new InvalidArgumentException(\sprintf('Invalid scope name: "%s" is reserved.', $name));
            }

            $scope = $scopeConfig['scope'] ?? null;
            unset($scopeConfig['scope']);
            $cachingOptions = $scopeConfig['caching'] ?? ['enabled' => false];
            unset($scopeConfig['caching']);
            $rateLimiter = $scopeConfig['rate_limiter'] ?? null;
            unset($scopeConfig['rate_limiter']);
            $retryOptions = $scopeConfig['retry_failed'] ?? ['enabled' => false];
            unset($scopeConfig['retry_failed']);

            if (null === $scope) {
                $baseUri = $scopeConfig['base_uri'];
                unset($scopeConfig['base_uri']);

                $container->register($name, ScopingHttpClient::class)
                    ->setFactory([ScopingHttpClient::class, 'forBaseUri'])
                    ->setArguments([new Reference('http_client.transport'), $baseUri, $scopeConfig])
                    ->addTag('http_client.client')
                    ->addTag('kernel.reset', ['method' => 'reset', 'on_invalid' => 'ignore'])
                ;
            } else {
                $container->register($name, ScopingHttpClient::class)
                    ->setArguments([new Reference('http_client.transport'), [$scope => $scopeConfig], $scope])
                    ->addTag('http_client.client')
                    ->addTag('kernel.reset', ['method' => 'reset', 'on_invalid' => 'ignore'])
                ;
            }

            if ($this->readConfigEnabled('http_client.scoped_clients.'.$name.'.caching', $container, $cachingOptions)) {
                $this->registerCachingHttpClient($cachingOptions, $scopeConfig, $name, $container);
            }

            if (null !== $rateLimiter) {

Review comment (suggestion):
instead of introducing this separate service, we could register `$name` with the initial service (which could even be a DI alias instead of this `current()` hack in the factory) and then registering ScopingHttpClient as a decorator of that service, allowing to configure the decoration priority even for cases where ScopingHttpClient should not be the outer one (see UriTemplateHttpClient which is still on the outside).

Code after:

        if (ContainerBuilder::willBeAvailable('guzzlehttp/uri-template', \GuzzleHttp\UriTemplate\UriTemplate::class, [])) {
            $container->setAlias('http_client.uri_template_expander', 'http_client.uri_template_expander.guzzle');
        } elseif (ContainerBuilder::willBeAvailable('rize/uri-template', \Rize\UriTemplate::class, [])) {
            $container->setAlias('http_client.uri_template_expander', 'http_client.uri_template_expander.rize');
        }

        $container
            ->getDefinition('http_client.uri_template')
            ->setArgument(2, $defaultUriTemplateVars);

        foreach ($config['scoped_clients'] as $name => $scopeConfig) {
            if ($container->has($name)) {
                throw new InvalidArgumentException(\sprintf('Invalid scope name: "%s" is reserved.', $name));
            }

            $scope = $scopeConfig['scope'] ?? null;
            unset($scopeConfig['scope']);
            $cachingOptions = $scopeConfig['caching'] ?? ['enabled' => false];
            unset($scopeConfig['caching']);
            $rateLimiter = $scopeConfig['rate_limiter'] ?? null;
            unset($scopeConfig['rate_limiter']);
            $retryOptions = $scopeConfig['retry_failed'] ?? ['enabled' => false];
            unset($scopeConfig['retry_failed']);

            $transport = $name.'.transport';
            $container->register($transport, HttpClientInterface::class)
                ->setFactory('current')
                ->setArguments([[new Reference('http_client.transport')]])
            ;

            if (null === $scope) {
                $baseUri = $scopeConfig['base_uri'];
                unset($scopeConfig['base_uri']);

                $container->register($name, ScopingHttpClient::class)
                    ->setFactory([ScopingHttpClient::class, 'forBaseUri'])
                    ->setArguments([new Reference($transport), $baseUri, $scopeConfig])
                    ->addTag('http_client.client')
                    ->addTag('kernel.reset', ['method' => 'reset', 'on_invalid' => 'ignore'])
                ;
            } else {
                $container->register($name, ScopingHttpClient::class)
                    ->setArguments([new Reference($transport), [$scope => $scopeConfig], $scope])
                    ->addTag('http_client.client')
                    ->addTag('kernel.reset', ['method' => 'reset', 'on_invalid' => 'ignore'])
                ;
            }

            if ($this->readConfigEnabled('http_client.scoped_clients.'.$name.'.caching', $container, $cachingOptions)) {
                $this->registerCachingHttpClient($cachingOptions, $scopeConfig, $transport, $container);