Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

DI Extensions can not use parameters from app main configuration #309

Open
forgie1 opened this issue Feb 9, 2024 · 8 comments
Open

DI Extensions can not use parameters from app main configuration #309

forgie1 opened this issue Feb 9, 2024 · 8 comments

Comments

@forgie1
Copy link

forgie1 commented Feb 9, 2024

Version: 3.2.0

Bug Description

config/common.neon

parameters:
	secretDir: 'mySecretDir'

extensions:
	myDiExtension: Plugin\DIExtension

DIExtension class

...
class DIExtension extends CompilerExtension
{

	public function loadConfiguration()
	{
		$this->compiler->loadConfig(__DIR__ . '/di.neon');
	}

}

di.neon

services:
	- Plugin\MyService(%secretDir%)

Parameter secretDir is not exchanged (translated) with its value mySecretDir

Expected Behavior

Parameter secretDir will be "translated" to its value mySecretDir

Possible Solution

Load configs in \Nette\DI\Compiler::processExtensions() before running this $first extensions:

$first = $this->getExtensions(Extensions\ParametersExtension::class) + $this->getExtensions(Extensions\ExtensionsExtension::class);
...
@forgie1
Copy link
Author

forgie1 commented Feb 11, 2024

Prior version 3.2.0 this actually worked.
Will it be working again, or shall we solve it different way?

@dg
Copy link
Member

dg commented Feb 12, 2024

In this case, the loadDefinitionsFromConfig() method should be used rather than loadConfig(). There was also a problem with expanding parameters, but it's fixed in 3.2-dev

class DIExtension extends CompilerExtension
{

	public function loadConfiguration()
	{
		$config = $this->loadFromFile(__DIR__ . '/di.neon');
		$this->loadDefinitionsFromConfig($config['services']);
	}

}

Before version 3.2.0 it expanded parameters only inside services but not anywhere else, now it is consistent.

@forgie1
Copy link
Author

forgie1 commented Feb 15, 2024

Thank you, this way it is working again.

@forgie1 forgie1 closed this as completed Feb 15, 2024
@forgie1
Copy link
Author

forgie1 commented Feb 17, 2024

What is not working this way is:

config file in the main app

services:
	service.def:
		factory: FQNofService

DI Extension config file loaded via ... $this->loadDefinitionsFromConfig($config['services']);

services:
	service.def:
		setup:
			- register(FQN1())
			- register(FQN2())

result is:

Nette\DI\ServiceCreationException
Service 'service.def': Factory and type are missing in definition of service.

This was also working prior 3.2.0 using

...
	public function loadConfiguration()
	{
		$this->compiler->loadConfig(__DIR__ . '/di.neon');
	}

In 3.2.0 it is not expanding parameters if $this->compiler->loadConfig() is used or above mentioned Exception is thrown if $this->loadDefinitionsFromConfig($config['services']); is used.

What is the proper way, how to load DI Extension's config.neon file, incl. expanding parameters of services and preventing this DI\Exception to be thrown in v3.2.0?

@forgie1 forgie1 reopened this Feb 17, 2024
@forgie1
Copy link
Author

forgie1 commented Mar 4, 2024

@dg shall we wait for any update on this issue, or shall we achieve functionality of adding setup: to services from the main App in the DI Extension .neon files another way (our own) -- not using any of Nette methods $this->compiler->loadConfig() || $this->loadDefinitionsFromConfig($config['services']); in the DI Extension?

@dg
Copy link
Member

dg commented Mar 6, 2024

Look, I think your use case is very unusual, so it's definitely better if you solve it yourself.

@forgie1
Copy link
Author

forgie1 commented Apr 4, 2024

OK, I tried it, but it looks the problem is broader.
One must choose:

  • to use $this->compiler->loadConfig() ---> parameters will not be expanded
  • or to use $this->loadDefinitionsFromConfig($config['services']); --> named services loaded this way are not recognized at all using @serviceName in any other .neon file

I mean this:

.neon file in DI Extension

services:
	- Plugin\MyService1(%parameterToBeExpanded%)
	myService2:
		factory: Plugin\MyService2

.neon file is loaded via $this->loadDefinitionsFromConfig() in the DIExtension so parameters are expanded.

.neon file in the main app

services:
	someService:
		factory: ServiceFQN
		setup:
			- attach(@myService2)

The result is Nette\DI\ServiceCreationException:
Reference to missing service 'myService2'

So basically all services must be registered in the main App .neon files, not in .neon files of DIExtension package, only then:

  • %parameters% will be expanded
  • @serviceNames will be possible to use in .neon files

It doesn't look flexible to me -- to use DIExtension is quite complicated this way, if only one of services in the .neon file needs its parameter to be expanded and @serviceName is used in other neon file. It is forcing us to move all services to main app .neon files, or to avoid using %parameters% in DIE, or to use other workaround.

@forgie1
Copy link
Author

forgie1 commented Apr 4, 2024

If $this->compiler->loadConfig() would also expand parameters used in services, all the problems mentioned above would be solved and call of $this->loadDefinitionsFromConfig() would not be needed.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants