Problem/Motivation

The use of the #[Symfony\Component\DependencyInjection\Attribute\Autowire] attribute in ContainerInjectionInterface and ContainerFactoryPluginInterface class constructors is supported since #3394870: Allow controller service wiring via constructor parameter attributes and #3452852: Add create() factory method with autowired parameters to PluginBase, but so far, only services can be autowired this way.

Since service class constructors can use the attribute to autowire container parameters as well, it would be useful to extend this functionality to AutowireTrait /AutowiredInstanceTrait. For an example, see

Drupal\rest\Plugin\views\display\RestExport

, where the create() method inejcts the authentication_providers and serializer.format_providers container parameters.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Issue fork drupal-3558292

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

godotislate created an issue. See original summary.

godotislate’s picture

Issue summary: View changes
godotislate’s picture

Issue summary: View changes
dimitriskr’s picture

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

longwave made their first commit to this issue’s fork.

longwave’s picture

Status: Active » Needs review

Implemented this, with test coverage for the entire trait.

claudiu.cristea’s picture

I'm expecting that we can even autowire a plain value. If we can pass a simple constant/value in *.services.yml, why wouldn't that be possible by autowiring? Looking to \Symfony\Component\DependencyInjection\Attribute\Autowire::__construct(), I see that it's possible to do by passing the $value param, e.g., #[Autowire(value: 'foo')]

longwave’s picture

@claudiu.cristea that is what #3533263: AutowireTrait has wrong behavior for literal string values is for, let's solve that separately?

godotislate’s picture

Status: Needs review » Reviewed & tested by the community

This looks good to me. I was surprised there wasn't already a dedicated AutowiredInstanceTrait test, so that was good to see.

This will conflict hard with #3558306: Support automatic setter injection using the #[Required] attribute in AutowireTrait/AutowiredInstanceTrait, though, but I guess we'll just see which gets in first.

claudiu.cristea’s picture

@claudiu.cristea that is what #3533263: AutowireTrait has wrong behavior for literal string values is for, let's solve that separately?

Sure, I've missed that issue.

BTW, I've been working for the same in Drush https://github.com/drush-ops/drush/pull/6061. I hit quite a lot of complexity because Drush handles two containers: Drupal's and its own (which is League)

claudiu.cristea’s picture

longwave’s picture

Status: Reviewed & tested by the community » Needs work
longwave’s picture

Status: Needs work » Needs review

Rebased and combined with #3558306: Support automatic setter injection using the #[Required] attribute in AutowireTrait/AutowiredInstanceTrait so you can also use setter injection for container parameters if you need to.

godotislate’s picture

1 question on the MR.

longwave’s picture

Added test for nullable services, also merged the setter test into the main test which reduces some duplication and proves that we can use all features simultaneously.

godotislate’s picture

Status: Needs review » Reviewed & tested by the community

Nice work! lgtm.

godotislate’s picture

longwave’s picture

I realised this doesn't support default values properly, e.g.

public function __construct(#[Autowire('%some.parameter%') public string $parameter = 'default') {}

This will fail if some.parameter is not set - but this feels like an edge case that we can handle in a followup if we need the feature.

godotislate’s picture

I agree that it can be handled in a follow up.

A workaround in the interim would be to make the parameter nullable and then assign it to a default value in the constructor if NULL.

godotislate’s picture

Title: Support passing container parameters with the Autowire attribute in AutowireTrait and AutowireInstanceTrait » Support passing container parameters with the Autowire attribute in AutowireTrait and AutowiredInstanceTrait
alexpott’s picture

Version: main » 11.x-dev
Status: Reviewed & tested by the community » Fixed

I considered asking for similar optimisations that Symfony uses ir. to check if the first character is a % before doing the regex but I decided that felt like premature optimisation.

Committed and pushed 73c6e0ac22d to main and 0a46fe24b9e to 11.x. Thanks!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • alexpott committed 0a46fe24 on 11.x
    task: #3558292 Support passing container parameters with the Autowire...

  • alexpott committed 73c6e0ac on main
    task: #3558292 Support passing container parameters with the Autowire...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.