Reputation: 1920
This is for Symfony 4.
I need to implement application (not bundle), configuration parameters using DependencyInjection\Configuration and DependencyInjection\AppExtension.
I created both classes as I would for a bundle. The namespace for each is App\DependencyInjection.
The file and class names are Configuration and AppExtension, respectively and are located in src/DependencyInjection/.
The Configuration currently just defines two scalar nodes for simplicity.
// src/DependencyInjection/Configuration.php
namespace App\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder( )
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root( 'app' );
$rootNode
->addDefaultsIfNotSet()
->children()
->scalarNode( 'a1' )
->defaultValue( 'I am the default value for a1' )
->end()
->scalarNode( 'a2' )
->defaultValue( 'I am the default value for a2' )
->end()
->end();
return $treeBuilder;
}
}
The AppExtension class implements two methods: __construct() and load().
The __construct() method simply echos its method name.
The load() method currently does a die( __METHOD__ ); just to ensure that I know if it's called. It isn't.
// src/DependencyInjection/AppExtension.php
namespace App\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
class AppExtension extends Extension
{
public function __construct()
{
echo __METHOD__ . "()\n";
}
public function load( array $configs, ContainerBuilder $container )
{
die( __METHOD__ );
}
}
I also created a config file:
# config/app.yml
app:
a1: 'A one'
a2: 'A two'
The answer to this question indicates that I need to include a call to $container->registerExtension() in the configureContainer() method of my src/kernel.php file so I added that.
protected function configureContainer( ContainerBuilder $container, LoaderInterface $loader )
{
$container->registerExtension( new AppExtension() );
...
}
When I run the console cache:clear command, the constructor for AppExtension is called, but the load() method never is.
Running the console debug:config app command results in this error:
No extensions with configuration available for "app".
What am I missing?
TIA
Upvotes: 4
Views: 1750
Reputation: 21
In the initial post there was just one line missing to get it work without creating an extra bundle:
src/DependencyInjection .
-- AppExtension .
-- AppConfiguration
In src/Kernel.php:
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
{
//...
$container->registerExtension(new AppExtension());
$container->loadFromExtension('app'); //this was missing in initial question
//...
}
Upvotes: 2
Reputation: 1920
So. I have a solution.
It takes three things beyond the normal Configuration and AppExtension classes in src/DependencyInjection/
Implement an empty App\AppBundle class that extends Bundle and place it in src/
// src/AppBundle.php
namespace App;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AppBundle extends Bundle {}
Add an entry for the bundle to the array returned by config/bundles.php
<?php
// config/bundles.php
return [
...
App\AppBundle::class => ['all' => true],
]
Place your configuration parameters in config/packages/app.yaml
# config/packages/app.yaml
app:
a1: 'A1 from app.yaml'
a2: 'A2 from app.yaml'
array_one:
a: { attr1: 'attribute one', attr2: 'two' }
b: { attr1: 'attribute one', attr2: 'two' }
This is actually working for me.
By the way, doing it this way, you do not need to register the extension in Kernel.php.
Upvotes: 1