Frank B
Frank B

Reputation: 3697

using service into service depending on configuration in thrid-party bundle

I am busy to port my third-party bundle from symfony 3 to symfony 4. I have my own service inside this bundle. Let's call it 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;
    }

    // ...
}

I have problems with the second injection 'UserCheckerInterface' which must inject another container service depending on my bundle configuration.

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;
    }

}

And finally inside my bundle the services.yaml:

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

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

This works but if i move the _defaults: bind section from the bundle's service.yaml to the main service.yaml outside the third-party bundle than it doesn't. This means that anyone which uses my third-party bundle still cannot use another userChecker. I tried something like:

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

but it gives a string as result instead of an instance. Somebody have a clue for me?

Upvotes: 1

Views: 89

Answers (1)

SilvioQ
SilvioQ

Reputation: 2072

You must configure your service in Extension class

<?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"]));
    }
}

Upvotes: 1

Related Questions