Skip to content
New issue

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

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

Already on GitHub? Sign in 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.

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

No branches or pull requests

2 participants