Solonl
Solonl

Reputation: 2502

How do I prevent defining an alias in config/services.yaml for a bundle?

I have a bundle, which I like to be able to be injected into a controller for example. The only thing I want a user to do is register the bundle. And then be free to inject the service anywhere they like:

namespace App\Bundles;

class MyService
{
    private $config;
    public function __construct(array $options)
    {
        $this->config= $options;
    }

    public function hello()
    {
        echo "Hello world";
    }
}

I have tried to define this line in config/services.yaml:

App\Bundles\MyService: '@bundle_service'

This seems to be working, but I don't want users to do this.

This is my Configuration class:

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder("my_bundle");
        $treeBuilder->getRootNode()
            ->children()
                ->arrayNode('author')
                    ->children()
                        ->scalarNode("name")->end()
                    ->end()
                ->end()
            ->end();

        return $treeBuilder;
    }
}

And the my_bundle config file, which is just a test so far:

my_bundle:
  author:
    name: "Name"

My Bundle extension class:

class MyBundleExtension extends Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {
        $loader = new YamlFileLoader(
            new FileLocator(__DIR__ .'/../Resources/config')
        );

        $loader->load('services.yaml');

       $configuration = new Configuration();
       $config = $this->processConfiguration($configuration, $configs);

        $container->setDefinition('bundle_service', new Definition(MyService::class, [$config]));
        $container->setAlias(MyService::class, 'bundle_service');
    }
}

My bundle class:

class MyBundle extends Bundle
{
    public function getContainerExtension()
    {
        return new MyBundleExtension();
    }
}

What am I missing. Everything is working, except I have to define this line App\Bundles\MyService: '@bundle_service' in config/services.yaml which I don't want my users to do. In MyBundleExtension I have provided the right definition:

        $container->setDefinition('bundle_service', new Definition(MyService::class, [$config]));
        $container->setAlias(MyService::class, 'bundle_service');

When I leave out the config/services.yaml code I get this error:

Cannot autowire service "App\Bundles\MyService": argument "$options" of method "__construct()" 

Upvotes: 0

Views: 218

Answers (2)

Heyden7611
Heyden7611

Reputation: 174

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');

             $container->setParameter('my_bundle.author.name', $config['author']['name']);
        }
}

Next

Declare service in config/services.yaml

my_bundle.my_service.service:
    class: App\Bundles\MyService
    public: true
    arguments:
        - '%my_bundle.author.name%'

Upvotes: 0

Heyden7611
Heyden7611

Reputation: 174

Create service with variable

services:
    # ...

    App\Updates\SiteUpdateManager:
        arguments:
            $adminEmail: '%admin_email%'

Or

Construct your service with

use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

class MessageGenerator
{
    private $params;

    public function __construct(ParameterBagInterface $params)
    {
        $this->params = $params;
    }

    public function someMethod()
    {
        $parameterValue = $this->params->get('my_bundle.author.name');
        // ...
    }
}

Upvotes: 1

Related Questions