Skip to content

Add a note about configuring controllers without autowire/autoconfigure #18841

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

Closed
wants to merge 1 commit into from

Conversation

javiereguiluz
Copy link
Member

Fixes #16579.

resource: '../src/Controller/'
tags: ['controller.service_arguments', 'container.service_subscriber']
calls:
- setContainer: ['@service_container']
Copy link

@AndreasA AndreasA Sep 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you sure service_container is correct here as one needs only the service locator instance of the service subscriber and not the full container or is the service ID replaced here in case the container.service_subscriber is used?

Though I think from the compiler pass it should be ContainerInterface or serviceproviderinterface

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the config shown, it worked for me when disabling autowire/autoconfigure. Other configs didn't work for me.

If you can, please tell me the exact config to try and I'll report the results here. Thanks!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi @javiereguiluz it is possible that it is correct but e.g. in other bundles like the user bundle https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/config/registration.xml#L26 this was used for the call.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@javiereguiluz I have now tested it and with Symfoyn 5.4 at least, if I use

calls:
    - setContainer: [ '@Psr\Container\ContainerInterface' ]

then I get Symfony\Component\DependencyInjection\Argument\ServiceLocator as class of the container.

If I use

calls:
    - setContainer: ['@service_container']

I get ContainerIjSHgNp\App_KernelDevDebugContainer as class of the container.

The first one seems to be correct as the second one is the full service container which might actually not have all relevant services.

Copy link

@AndreasA AndreasA Sep 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and if I use $this->container->get('parameter_bag') with the first it works the second I get service or alias has been removed or inlined when the container was compiled.

Copy link

@AndreasA AndreasA Sep 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw. I think the config should only be done for a specific controller class as example, as controllers that do not extends AbstractController might fail otherwise (they might not use setcontainer).

sorry for all those comments 😄

Copy link
Member

@alexandre-daubois alexandre-daubois Sep 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may have been a bit fast on approval 😄 I also tried with a minimalistic example:

class TestController extends AbstractController implements ServiceSubscriberInterface
{
    #[Route('/')]
    public function index(): Response
    {
        return new Response();
    }
}

Config:

services:
    # ...

    App\Controller\:
        resource: '../src/Controller'
        public: true
        autowire: false
        autoconfigure: false
        tags: ['controller.service_arguments', 'container.service_subscriber']
        calls:
            - setContainer: ['@service_container']

And I also have the The "parameter_bag" service or alias has been removed or inlined when the container was compiled error 🤔

'@Psr\Container\ContainerInterface' works also well for me, tested on 6.4. I guess we should document this with this service.

I wonder if it isn't related to this known bug actually. I'm not sure, but it really looks like it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that at this point, we should ask @nicolas-grekas for advice about what to do here. Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is never a reason to inject the service container anywhere, so this is wrong. It will fail when any private services are accessed. It happens that AbstractController consumes services that are declared public (the router?) But this works by chance. Instead one should declare a scoped locator. There's a way to define one using tags, I don't remember how exactly and I'm AFK. Anyone does?

Copy link

@AndreasA AndreasA Sep 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The locator should be defined by the container.servicer_subscriber tag in this case as the Abstractconroller provides the corresponding subscribedservices method., at least I think so?
otherwise it is even more configuration to get all correct arguments into the abstractcontroller (which might even change in the future).
not sure what the ID of that one is to inject it. I think however, ContainerInterface should work because that is what autowiring binds the service for - otherwise it would not work correctly with autowiring but not sure if this is the preferred service ID.

might also be something to add to the service subscriber/locator documentation because I don't think it is mentioned there either.

Copy link
Member

@alexandre-daubois alexandre-daubois left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

@alexandre-daubois
Copy link
Member

alexandre-daubois commented Oct 30, 2023

Do you need help to finish this one @javiereguiluz? 🙂 Or maybe it's ready?

@javiereguiluz
Copy link
Member Author

@alexandre-daubois could you please take over this PR? Because of the long discussion, this is now more confusing to me than at the beginning. I'll close here and if you have some time, you can take part or all of the changes here in your PR. Thanks a lot!

@alexandre-daubois
Copy link
Member

@javiereguiluz of course! I'll keep you updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants