loadDefinitions → loadDefinitionsFromConfig in Nette 3.0

MichalHaltuf
Bronze Partner | 14
+
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?

CZechBoY
Member | 3608
+
+1
-

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

MichalHaltuf
Bronze Partner | 14
+
+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);
dkorpar
Member | 135
+
+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.