Autowiring does not support union type and default value.

Created on 29 January 2024, about 1 year ago
Updated 23 February 2024, about 1 year ago

Problem/Motivation

I haven't found a practical example in the Drupal Core, but support for union and intersection types in autowiring will be useful in some cases.

Steps to reproduce

Do something like

Example:

public function __construct(
    protected FooClass|BarClass $service,
) {}
public function __construct(
    protected FooClass&BarClass $service,
) {}

We will receive an AutowiringFailedException even if the services exist.

Proposed resolution

TBD

Remaining tasks

Update issue summary
Review

User interface changes

NA

API changes

TBD - not sure

Data model changes

NA

Release notes snippet

TBD

πŸ› Bug report
Status

Needs work

Version

11.0 πŸ”₯

Component
BaseΒ  β†’

Last updated 16 minutes ago

Created by

πŸ‡ΊπŸ‡¦Ukraine chesn0k Ukraine, Odessa

Live updates comments and jobs are added and updated live.
  • Needs issue summary update

    Issue summaries save everyone time if they are kept up-to-date. See Update issue summary task instructions.

Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @chesn0k
  • πŸ‡¬πŸ‡§United Kingdom longwave UK

    Not sure how you would autowire an intersection type, because we wire by interface name it can't be two at once? But union types should be possible, we should inject the first match I suppose.

  • πŸ‡ΊπŸ‡¦Ukraine chesn0k Ukraine, Odessa

    If the Drupal Core provided aliases for the serializer it would look something like this:

    services:
      serializer:
        class: Symfony\Component\Serializer\Serializer
        arguments: [{  }, {  }]
      Symfony\Component\Serializer\Normalizer\SerializerInterface: '@serializer'
      Symfony\Component\Serializer\Normalizer\DenormalizerInterface: '@serializer'
      Symfony\Component\Serializer\Normalizer\NormalizerInterface: '@serializer'
    

    Assumed controller constructor:

    public function __construct(
        protected NormalizerInterface&DenormalizerInterface $normalizer,
    ) {}
    

    In this case, we can check if all interfaces of a intersection type refer to the same service. If any of the interfaces is not an alias or refers to another service throw an AutowiringFailedException.

    For a union type, we can iterate over all types until the first service found.

    What do you think about it?

  • πŸ‡¬πŸ‡§United Kingdom longwave UK

    I think that's pretty edge case and I still don't see an immediate use for it (we don't appear to have any constructors that would require this right now), so it depends how much overhead it adds.

  • πŸ‡ΊπŸ‡¦Ukraine chesn0k Ukraine, Odessa

    I think this would require a recursive call, okay let's skip that case for now.

  • πŸ‡ΊπŸ‡¦Ukraine chesn0k Ukraine, Odessa
  • Merge request !6375Add support for union type. β†’ (Open) created by chesn0k
  • Pipeline finished with Failed
    about 1 year ago
    Total: 178s
    #84394
  • Pipeline finished with Success
    about 1 year ago
    Total: 500s
    #84624
  • πŸ‡ΊπŸ‡¦Ukraine chesn0k Ukraine, Odessa
  • Status changed to Needs review about 1 year ago
  • πŸ‡ΊπŸ‡¦Ukraine chesn0k Ukraine, Odessa
  • Status changed to Needs work about 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Could the issue summary be updated to include proposed solution to bug?

    Not sure if this is an API change.

    I added the missing sections but left TBD for sections I can't answer

    Test coverage appears to be there https://git.drupalcode.org/issue/drupal-3417735/-/jobs/714169

Production build 0.71.5 2024