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

Allow to bind inline services by type and name #40469

Closed
vudaltsov opened this issue Mar 15, 2021 · 5 comments
Closed

Allow to bind inline services by type and name #40469

vudaltsov opened this issue Mar 15, 2021 · 5 comments
Labels
DependencyInjection Feature Help wanted Issues and PRs which are looking for volunteers to complete them.

Comments

@vudaltsov
Copy link
Contributor

return function(ContainerConfigurator $configurator) {
    $services = $configurator->services()
        ->defaults()
        ->bind(Foo::class.' $foo', inline_service(Foo::class))
    ;
};

Currently it throws Invalid binding for service "": named arguments must start with a "$", and FQCN must map to references. Neither applies to binding "Foo $foo", while binding inline service just by name works.

@nicolas-grekas
Copy link
Member

We might improve the error message, but what it says is that only references are allowed when binding services, and this looks legit to me. Otherwise, there is some non-intuitive issue that is going to happen, eg: should all inline services lead to different instances or should they all refer to the same one ? (note: this would need a ... reference).

@vudaltsov
Copy link
Contributor Author

vudaltsov commented Mar 24, 2021

@nicolas-grekas, I understand your reasoning, but as a developer I face the following inconsistency. I can bind an inline service by name only, but cannot bind by type and name. So it would be more logical to forbid binding inline services completely, or allow to bind them both ways.

@nicolas-grekas
Copy link
Member

Would you mind investigating in the code where this difference happens? I'm surprised that binding by name-only works with inline services.

@vudaltsov
Copy link
Contributor Author

if (!preg_match('/^(?:(?:array|bool|float|int|string)[ \t]*+)?\$/', $nameOrFqcn) && !$valueOrRef instanceof Reference) {
throw new InvalidArgumentException(sprintf('Invalid binding for service "%s": named arguments must start with a "$", and FQCN must map to references. Neither applies to binding "%s".', $this->id, $nameOrFqcn));
}

The first matching group in the regexp is optional. Thus, during a call ->bind('$name', inline_service()), preg_match evaluates to true and !preg_match evaluates to false, which immediately prevents exception from being thrown.

@nicolas-grekas
Copy link
Member

PR welcome @vudaltsov, let's make this consistent.

@chalasr chalasr added the Help wanted Issues and PRs which are looking for volunteers to complete them. label Oct 18, 2021
@fabpot fabpot closed this as completed in b8656d4 Jan 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DependencyInjection Feature Help wanted Issues and PRs which are looking for volunteers to complete them.
Projects
None yet
Development

No branches or pull requests

4 participants