Skip to content

Autowire error with Symfony Flex when configuring argument by name #23308

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
ByScripts opened this issue Jun 27, 2017 · 14 comments
Closed

Autowire error with Symfony Flex when configuring argument by name #23308

ByScripts opened this issue Jun 27, 2017 · 14 comments

Comments

@ByScripts
Copy link

Q A
Bug report? yes
Feature request? no
BC Break report? no
RFC? no
Symfony version 3.3.2

There seems to be a problem with autowiring when using Symfony Flex, but not when using a standard symfony new project.

When configuring an argument by name (arguments: { $argName: 'value' }), other arguments are no longer autowired.

At the beginning, I had this service, which was working fine (autowiring works as expected):

namespace App\Service;

class FirstClass
{
  public function __construct(SecondClass $secondClass)
  {
        // ...
  }
}

But then I needed to add a second argument, a plain string. So I did it like this:

public function __construct(SecondClass $secondClass, string $myString)

Then I updated container.yaml accordingly:

services:
  App\Service\FirstClass:
    arguments:
      $myString: 'Some string'

But now I have this error:

Fatal error: Uncaught Symfony\Component\DependencyInjection\Exception\RuntimeException: Invalid constructor argument 2 for service "App\Service\FirstClass": argument 1 must be defined before. Check your service definition.

If I move the string argument to first position, then I have this error:

Type error: Too few arguments to function App\Service\FirstClass::__construct(), 1 passed in /.../srcDevDebugProjectContainer.php on line 184 and exactly 2 expected in /.../src/Service/FirstClass.php

Here is two demo project, configured the same way. One with Symfony Flex, other as a standard symfony new project:

Flex: https://github.com/ByScripts/sf-issue-autowire-flex
Standard: https://github.com/ByScripts/sf-issue-autowire

Just git clone, composer install, then run bin/console on both project.

@shude
Copy link
Contributor

shude commented Jun 27, 2017

If you want use a named arguments, just change definiton:

services:
  App\Service\FirstClass:
    arguments:
      [$myString: 'Some string']

@sstok
Copy link
Contributor

sstok commented Jun 27, 2017

Any name/value that starts with special character needs to be quoted: '$myString': 'Some string'

@shude
Copy link
Contributor

shude commented Jun 27, 2017

In this case quoted: '$myString': 'Some string' not works.

@ByScripts
Copy link
Author

ByScripts commented Jun 27, 2017

But:

1> It's not what the documentation says
2> In the "standard" Symfony install, it works
3> In the flex install, if I define manually the 2 arguments like below, it works too:

services:
  App\Service\FirstClass:
    $secondClass: '@App\Service\SecondClass'
    $myString: 'Some string'

I don't think the problem come from the definition. It's just that with Flex install, when configuring an argument by name, other arguments are no longer autowired

@ogizanagi
Copy link
Contributor

ogizanagi commented Jun 27, 2017

@ByScripts : autowiring is not enabled in container.yml. Just in etc/packages/app.yaml. It's a per-file directive (_defaults).

Enable autowiring for all services declared inside the file (+ private by default & autoconfigure) by adding this to the container.yml file:

services:
    _defaults: { public: false, autowire: true, autoconfigure: true }
    # ...

@stof
Copy link
Member

stof commented Jun 27, 2017

or enable autowiring just for this service

@ByScripts
Copy link
Author

ByScripts commented Jun 27, 2017

Thank you.

Yet, autowiring works if I don't add the string param... why ?

Edit: Nevermind, I understand what @ogizanagi means. Thank you.

@ogizanagi
Copy link
Contributor

It's not autowiring, it the named arguments feature: #21383

@ByScripts
Copy link
Author

So... now I understand. But I think it's a "strange" behavior.

The app is configured to autowire by default (packages/app.yaml), which is great, and somewhat logical.

But I think it'll be pretty common to need to configure a named parameter. And since for that we declare the service in container.yaml, it is no longer autowired.

Other solution would be to use the app.yaml file, but in this case the container.yaml become useless, and it would feel pretty "bad".

Last is what @ogizanagi proposes. Addind the _defaults to container.yaml. Which is the "best practice" I suppose.

But should not the container.yaml contains these _defaults by default when creating the project?

Because it feels inconsistent to me, no?

@shude
Copy link
Contributor

shude commented Jun 27, 2017

I clone your repo and try my solution with:

services:
  App\Service\FirstClass:
    arguments:
      -$myString: 'Some string'

And it works without any configuration. If you use named arguments just define it with array.

@ByScripts
Copy link
Author

@shude It fixes the error when running bin/console, but it's not working, because what it does is passing an array as first argument.

I created a Command, then injected FirstClass in its constructor. When I run the command, I get this error:

Type error: Argument 1 passed to App\Service\FirstClass::__construct() must be an instance of App\Service\SecondClass, array given

Like @ogizanagi said, autowiring is not configured in this file (container.yaml), so it can't work without specifying each argument (or by adding _defaults).

@shude
Copy link
Contributor

shude commented Jun 27, 2017

Sorry, I was wrong. If manualy set autowire to true it works fine. i think, It should be written in the documentation

@nicolas-grekas
Copy link
Member

@ByScripts can you close here (and maybe open a doc PR or issue also?)

@HeahDude
Copy link
Contributor

I've just opened symfony/symfony-docs#8242, we can close here.

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

No branches or pull requests

9 participants