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

SearchExtension: ignores classes that do not have autowired parameters #316

Open
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

h4kuna
Copy link
Contributor

@h4kuna h4kuna commented Jun 6, 2024

  • new feature
  • BC break? no
  • doc PR: no

Hello,
I use SearchExtension and I have primitive classes in project, but all these classes I must register to exclude section. I think if the class does not have autowired parameters it can be skipped.

Example:

Simple class

namespace Garage\Model;

class Foo
{
	public function __construct(
		public float $precipitation,
	)
	{
	}
}

Actual behavior throw exception:

  • Nette\DI\ServiceCreationException: Service of type Garage\Model\Foo: Parameter $precipitation in Foo::__construct() has no class type or default value, so its value must be specified. in /path/DI/Resolver.php:635

In this moment I must add class to search -> exclude.

New bahevior

If SearchExtension skip this class and I don't need dependency by another class, everything is ok.

If I need dependency by another class, for example Garage\Model\Baz. I get exception:

  • Nette\DI\ServiceCreationException: Service of type Garage\Model\Baz: Service of type Garage\Model\Foo required by $messenger in Baz::__construct() not found. Did you add it to configuration file?

I must manually register the class and I think it is legit. I can't think of a use case where it might be undesirable.

After apply this patch, the result is:
Snímek obrazovky z 2024-06-07 06-32-12

@JanTvrdik
Copy link
Contributor

This would make it hard to reason about why some service is not registered.

@h4kuna
Copy link
Contributor Author

h4kuna commented Jun 6, 2024

@JanTvrdik could you show me an example?

@h4kuna
Copy link
Contributor Author

h4kuna commented Jun 9, 2024

I want only reduce the exclude list, where you don't need to register services.

@h4kuna
Copy link
Contributor Author

h4kuna commented Jun 18, 2024

The similar condition is \ReflectionClass($class)::isInstantiable().

@dg
Copy link
Member

dg commented Jun 18, 2024

This is an absolutely fatal BC break.

@h4kuna
Copy link
Contributor Author

h4kuna commented Jun 19, 2024

Could you more explain the BC break to me, because I don't understand.

@mabar
Copy link
Contributor

mabar commented Jun 19, 2024

Service B depends on service A
Service B is loaded by search extension
Remove service A
Exception: Missing service B

Why?

Services don't even have to come from the same repository so the developer doesn't have control over service A. Service B not being registered instead of reporting that A is missing even though developer configured search extension to find it is really confusing behavior.

I am aware of this feature and was digging in Nette internals for 6 years now and I would still be lost if this happened to me.

@h4kuna
Copy link
Contributor Author

h4kuna commented Jun 21, 2024

@mabar Thank you for explain

I tried your example

class A
{
	public function __construct()
	{
	}
}

class B
{
	public function __construct(private A $a)
	{
	}
}
  • run, ok
  • remove A

Both classes are loaded by search extension and I get exception:
Nette\DI\ServiceCreationException: Service of type Garage\B: Class 'Garage\A' required by $a in B::__construct() not found. Check the parameter type and 'use' statements.

A is regstered, B is loaded in config:
Nette\DI\ServiceCreationException: Service (Garage\A::__construct()): Class 'Garage\A' not found.

B is registered, A is loaded: **Nette\DI\ServiceCreationException:
Service of type Garage\B: Class 'Garage\A' required by $a in B::__construct() not found. Check the parameter type and 'use' statements.

These use cases have legit exception. Nothing about missing Garage\B. But in this case is little bit worse

I revert A and add scalar parameter

class A
{
	public function __construct(string $foo)
	{
	}
}

Nette\DI\ServiceCreationException: Service of type Garage\B: Service of type Garage\A required by $a in B::__construct() not found. Did you add it to configuration file?

The response on question Did you add it to configuration file? is "No because I use search extension", but what happen if I add this class to config? Nette\DI\ServiceCreationException: Service of type Garage\A: Parameter $foo in A::__construct() has no class type or default value, so its value must be specified. It's reason why search engine does not find my class, because I must set up class A before use.

What do you think?

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

Successfully merging this pull request may close these issues.

4 participants