Использование сервиса в сервисе в зависимости от конфигурации в стороннем пакете

Я занят портированием своего стороннего пакета с Symfony 3 на Symfony 4. У меня есть собственный сервис внутри этого пакета. Назовем его MyService:

use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Security\Core\User\UserCheckerInterface;

class MyService
{
    private $params;
    private $userChecker;

    function __construct( ParameterBagInterface $params,
                          UserCheckerInterface  $userChecker )
    {
        $this->params = $params;
        $this->userChecker = $userChecker;
    }

    // ...
}

У меня проблемы со второй инъекцией «UserCheckerInterface», которая должна внедрить другую службу контейнера в зависимости от конфигурации моего пакета.

MyBundle/DependencyInjection/Configuration.php:

class Configuration implements ConfigurationInterface
{
    /**
     * {@inheritdoc}
     */
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('fbeen_user');

        $rootNode
            ->children()
                ->scalarNode('user_checker')->defaultValue('@security.user_checker.main')->end()
            ->end()
        ;

        return $treeBuilder;
    }

}

И, наконец, внутри моего пакета services.yaml:

services:
    _defaults:
        bind:
            $userChecker: '@security.user_checker.main'

    my_bundle.my_service:
        class: MyCompany\MyBundle\Service\MyService
        arguments: ['@parameter_bag'] 
        public: true

Это работает, но если я перенесу раздел _defaults: bind из пакета service.yaml в основной service.yaml вне стороннего пакета, то это не так. Это означает, что любой, кто использует мой сторонний пакет, по-прежнему не может использовать другой userChecker. Я пробовал что-то вроде:

services:
    _defaults:
        bind:
            $userChecker: '@%mycompany_mybundle.user_checker%'

но он дает строку в качестве результата вместо экземпляра. У кого-нибудь есть ключ для меня?

user_checker не является параметром контейнера. Вы должны объявить его в AppBundleExtension... проверить symfony.com/doc/current/bundles/configuration.html... и использовать replaceArgument для установки ссылки на службу
SilvioQ 02.02.2019 11:28
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
1
1
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны настроить свой сервис в классе Extension

<?php

namespace MyBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\Reference;

class MyBundleExtension extends Extension 
{
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);

        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
        $loader->load('services.yml');

        $definition = $container->getDefinition('my_bundle.my_service');
        $definition->replaceArgument(1, new Reference($config["user_checker"]));
    }
}

Это работает как шарм Сильвио! Большое спасибо, что нашли время, чтобы помочь мне с вашим примером

Frank B 02.02.2019 16:13

Другие вопросы по теме