-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[DependencyInjection] Add Parameter attribute to bind container parameters to services. #44780
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
Conversation
Hey! I think @fractalzombie has recently worked with this code. Maybe they can help review this? Cheers! Carsonbot |
I like this idea but what about binding services as well? I'm thinking just a single class DummyService
{
public function __construct(
#[Bind('@another.service.id')]
public AnotherService $service,
#[Bind('%kernel.debug%')]
public bool $isDebugEnv
) {
}
} This would be a shortcut to the following (which is possible now): #[Autoconfigure(bind: [
'$service' => '@another.service.id',
'$isDebugEnv' => '%kernel.debug%',
])]
class DummyService
{
public function __construct(public AnotherService $service, public bool $isDebugEnv)
{
}
} |
src/Symfony/Component/DependencyInjection/Attribute/Parameter.php
Outdated
Show resolved
Hide resolved
Isn't it already solved in some way with the |
Partially, but not for service ids themselves and this was what I was looking for. I'm envisioning this purely as a short-hand for |
The reason I did not consider it for services is that services are already automatically injected on top of already having the The other thing is that this accepts only parameters rather than a string with a parameter in it such as |
Yes, this would just be a shortcut for
To me, this argument applies to binding services as well as parameters.
Since |
Based on the various comments here, I think there is a misunderstand about what the |
So to clarify, for my second code block here. This would register the Looking at #39804.
Indeed, this was a misunderstanding on my part. So what I'm looking for and I believe @maldoinc is looking for (for parameters at least) is a way to take this config: services:
App\SomeService:
- '@some.other.service'
- '%some.parameter%' And use constructor parameter attributes to configure: class SomeService
{
public function __construct(
#[???('some.other.service')]
public AnotherService $service,
#[???('some.parameter')]
public string $parameter
) {
}
} |
@kbond the Autoconfigure attribute would register a binding applied on all (autoconfigured) service whose class is a DummyService or a child class of DummyService |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer requiring the %
around the parameter name, as this gives more flexibility, eg:
#[Parameter('%kernel.project_dir%/var/foo')]
@@ -38,6 +38,27 @@ | |||
*/ | |||
class AutowirePassTest extends TestCase | |||
{ | |||
/** | |||
* @requires PHP 8.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not needed anymore
|
||
class AutowiredParameterTest | ||
{ | ||
public function __construct(#[Parameter("parameter.test")] public string $testParam) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use single-quoted strings
…te (kbond) This PR was merged into the 6.1 branch. Discussion ---------- [DependencyInjection] add `Autowire` parameter attribute | Q | A | ------------- | --- | Branch? | 6.1 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | n/a | License | MIT | Doc PR | todo Replaces #45573 & #44780 with a single new `Autowire` attribute: ```php class MyService { public function __construct( #[Autowire(service: 'some_service')] private $service1, #[Autowire(expression: 'service("App\\Mail\\MailerConfiguration").getMailerMethod()') private $service2, #[Autowire(value: '%env(json:file:resolve:AUTH_FILE)%')] private $parameter1, #[Autowire(value: '%kernel.project_dir%/config/dir')] private $parameter2, ) {} } ``` Works with controller arguments as well: ```php class MyController { public function someAction( #[Autowire(service: 'some_service')] $service1, #[Autowire(expression: 'service("App\\Mail\\MailerConfiguration").getMailerMethod()') $service2, #[Autowire(value: '%env(json:file:resolve:AUTH_FILE)%')] $parameter1, #[Autowire(value: '%kernel.project_dir%/config/dir')] $parameter2, ): Response {} } ``` Commits ------- d43fe42 [DependencyInjection] add `Autowire` parameter attribute
Hi all.
This PR proposes the addition of a new Attribute to bind container parameters to services.
Motivation:
Seeing as Symfony has been adopting the usage of attributes to configure services, this would add the possibility to bind parameters and have services be self-contained instead of having their configuration split into multiple files.
In the application we develop most services which require parameters have their values declared in a Yaml file via the following syntax.
Downsides
Recently I also became aware of the
#[Autoconfigure(bind:['$isDebugEnv' => '%kernel.debug%'])]
syntax. This addresses the separation of the declaration into multiple files and follows the class when moved around. If this PR won't pass then this would be our preferred method once the application I help develop is upgraded to PHP 8.bind
and is also not refactored and is also duplicated.Proposal:
The
Parameter
(orBindParameter
, name tbd) attribute which is applied to parameters and properties (to account for promoted properties) and has the parameter name bound via a compiler pass. Currently only parameters are supported so the following is not a valid syntax#[Parameter("%kernel.logs_dir%/subdir")]
(also tbd).This would address the concerns from both previous approaches and in my opinion has a main advantage: It does not rely on strings for the argument name. The php community has been moving away for quite some time now from hard-coded strings to reference things. Classes now have the
::class
syntax, and references to functions, properties and methods went from strings and arrays to having first-class support with the new(...)
syntax.The downside of this new attribute would be that it is yet another way to do something that is already possible. On the other hand, Symfony has always had multiple options to do configuration (annotations and now attributes, yaml, xml, php).
Example:
Looking forward to your thoughts. Related issue: #40327