I'm creating a bundle for a few Symfony projects. This bundle contains one service and this service is created with a constructor containing an array as first and unique parameter. Developers who will use my bundle have to declare this array in the config/properties.yaml
file.
Here is how the array in the config/properties.yaml
is loaded. I use the new Symfony6 AbstractBundle class.
class LongitudeOnePropertyBundle extends AbstractBundle
{
public function getPath(): string
{
return \dirname(__DIR__);
}
public function configure(DefinitionConfigurator $definition): void
{
$definition->rootNode()
->children()
->arrayNode('extendable_entities')
->defaultValue([])
->scalarPrototype()->end()
->end()
->end()
->end();
}
public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void
{
$loader = new PhpFileLoader($builder, new FileLocator(__DIR__ . '/Resources/config/'));
$loader->load('services.php');
// dump($container->services()->get('longitude-one.property_bundle.property_service'));
$container->services()
->get('longitude-one.property_bundle.property_service')
->arg(0, $config['extendable_entities']);
// dump($container->services()->get('longitude-one.property_bundle.property_service'));
}
}
My service is very simple: a constructor with an array as parameter:
//src/Service.php
namespace LongitudeOne\PropertyBundle\Service;
class PropertyService
{
/**
* @var string[] list of all extendable classes
*/
private array $classes;
/**
* @param string[] $classes list of all extendable classes
*/
public function __construct(array $classes)
{
die('constructor is called');
}
Here is how I configure my services inside the bundle:
//src/Resources/config/services.php
return static function (ContainerConfigurator $container) {
$container->services()
->set('longitude-one.property_bundle.property_service', PropertyService::class)
->class(PropertyService::class)
->autoconfigure()
->autowire()
->public()
->arg(0, param('lopb.extendable_entities'));
dump($container->services()->get(PropertyService::class));
};
In my test application, as soon as my controller call my service with Dependency Injection Pattern, I got this error.
Cannot resolve argument $propertyService of "App\Controller\Admin\DashboardController::list()": Cannot autowire service "LongitudeOne\PropertyBundle\Service\PropertyService": argument "$classes" of method "__construct()" is type-hinted "array", you should configure its value explicitly.
In the service.php file, I added a dump to check that the bundle is well implemented. The container is dumped:
Symfony\Component\DependencyInjection\Loader\Configurator\ServiceConfigurator {#4798 ▼
#definition: Symfony\Component\DependencyInjection\Definition {#4800 ▼
-class: 'LongitudeOne\PropertyBundle\Service\PropertyService'
...
-autowired: true
...
#arguments: array:1 [▼
0 => []
]
}
...
#id: "LongitudeOne\PropertyBundle\Service\PropertyService"
-defaultTags: []
-container: Symfony\Component\DependencyInjection\Compiler
- I tried to replace the array parameter set by developer in the config/property.yaml file by an empty array ( [] ) ;
- I checked that bundle is well declared ;
- I checked that my services.php file (dump is well written) ;
- I tried to replace the constructor by a method and I added call('setClasses'), but method isn't called.
- I checked my service with
symfony console debug:container longitude-one
- After reading this question, I set my service as a public service.
/var/www # symfony console debug:container longitude-one
Information for Service "longitude-one.property_bundle.property_service"
========================================================================
---------------- -----------------------------------------------------
Option Value
---------------- -----------------------------------------------------
Service ID longitude-one.property_bundle.property_service
Class LongitudeOne\PropertyBundle\Service\PropertyService
Tags -
Public yes
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired yes
Autoconfigured yes
Usages none
What am I missing?