Search code examples
phpsymfonydependency-injectionsymfony-components

How to access dynamic references from other container items?


How can I pass a dynamic dependency from one registered container definition to another? In this case, a generic Database object wants to inherit from a generic Config object. The twist is config is not static, but loaded depending on a given environment variable.

Config pertinent methods

    public function __construct()
    {
        $configFile = 'example.config.yml';
        $yamlParser = new Parser();
        $reader = new Config\Reader($yamlParser);
        $configYaml = $reader->parse(file_get_contents($configFile));
        $config = new Config\Environment(getenv('SITE'), $configYaml);

        $this->config = $config;
    }

    public function getEnvironmentConfig()
    {
        return $this->config;
    }

Registering config is as simple as

$container->register('config', 'Config');

Database is currently added to the container as follows:

$container
    ->register('database', 'Database')
    ->addArgument($config->getEnvironmentConfig('Database', 'db.username'))
    ->addArgument($config->getEnvironmentConfig('Database', 'db.password'))
;

But I want to do something like

$container
        ->register('database', 'Database')
        ->addArgument(new Reference('config')->getEnvironmentConfig('Database', 'db.username'))
        ->addArgument(new Reference('config')->getEnvironmentConfig('Database', 'db.password'))
    ;

The $config in-PHP variable makes migrating from a PHP-built config impossible. I want to define the services in yaml force the container to:

  1. Instantiate Config
  2. Parse the config yaml file and create an environment-specific version
  3. Return this on a call to getEnvironmentConfig

Is this possible?


Solution

  • This was solved by using the Expression Language Component

    So you can easily chain method calls, for example:

    use Symfony\Component\ExpressionLanguage\Expression;
    $container->register('database', 'Database')
              ->addArgument(new Expression('service("config").getEnvironmentConfig("Database", "db.username")'));