loadDefinitions → loadDefinitionsFromConfig in Nette 3.0

5 months ago

MichalHaltuf
Backer | 11
+
0
-

Hello,
I'd like to ask: does the loadDefinitionsFromConfig changed its behaviour from previous loadDefinitions?

I'm trying to upgrade these lines to Nette v 3.0:

https://github.com/…xtension.php#…

Compiler::loadDefinitions($builder, [
    $serviceName = $this->prefix('handler.' . $handlerName) => $implementation,
]);

feeded with config.neon: https://github.com/…andlers.neon

monolog:
    handlers:
        - Monolog\Handler\BrowserConsoleHandler()
        - Monolog\Handler\ChromePHPHandler()
- Monolog\Handler\NewRelicHandler()

In Nette 3.0, the above lines return “Nette\DI\Compiler::loadDefinitions() is deprecated, use non-static Compiler::loadDefinitionsFromConfig(array $configList).”

So I changed them to:

$this->compiler->loadDefinitionsFromConfig([
    $serviceName = $this->prefix('handler.' . $handlerName) => $implementation,
]);

But the behaviour changed. While in 2.4 with loadDefinitions, the generated container looked like this:

public function createServiceMonolog__logger(): Kdyby\Monolog\Logger
{
    $service = new Kdyby\Monolog\Logger('app');

In Nette 3.0 with loadDefinitionsFromConfig, the generated container looks like this:

public function createServiceMonolog__logger(): Kdyby\Monolog\Logger
{
    $service = new Kdyby\Monolog\Logger(
        'app',
        [
            $this->getService('monolog.handler.0'),
            $this->getService('monolog.handler.1'),
            $this->getService('monolog.handler.2'),
        ]
    );

Sorry for (possibly) a rookie question, but there's some magic going on I do not understand. I understand that this is desired behaviour in most of the use case, but here not – I do not want to DI these services right away, because I need to set a different order of them and push them manually in the Kdyby\Monolog\Logger (see https://github.com/…xtension.php#…)

Can you please help me understand, what's going on in Nette 3.0 that wasn't in 2.4?

5 months ago

CZechBoY
Member | 3395
+
+1
-

What about $builder->addDefinition(…) or something like that?

5 months ago

MichalHaltuf
Backer | 11
+
+1
-

@CZechBoY Thanks for a hint.

How I solved it, for future reference (and in case someone else finds himself/herself in similar position):

foreach ($config['handlers'] as $handlerName => $implementation) {

    /* class of type Nette\DI\Definitions\ServiceDefinition $sd */
    $sd = new ServiceDefinition();
    $sd->setFactory($implementation)->setAutowired(FALSE);
    $serviceName = $this->prefix('handler.' . $handlerName);
    $builder->addDefinition($serviceName, $sd);

5 months ago

dkorpar
Member | 73
+
+1
-

@MichalHaltuf
just to warn U, this won't work with factory interfaces, possibly some other services as well. Also if U had some attributes passed in config file for services (like tags …) it won't be same anymore.