Gabf Hann
Gabf Hann

Reputation: 350

symfony v3.4 unable to guess autowiring

Symfony v3.4 is unable to guess the argument when using autowire feature.

Cannot autowire service "AppBundle\Service\MyServiceConfig": argument "$key" of method "__construct()" has no type-hint, you should configure its value explicitly.

I have also explicitly defined the argument but it still does not work, The argument is of type string of length 136 characters.

services:
     app.myservice.config:
         class: AppBundle\Service\MyServiceConfig
         public: true
         arguments: ["%app_key%"] #defined in parameter.yml

    app.myservice
         class: AppBundle\Service\MyService
         public: true
         arguments: ["@app.myservice.config"]

Which works absolutely fine I can see the expected results when I invoke the services.

However When I write AppExtension i get the above error:

app.twig.my_app_extension:
    class: AppBundle\Twig\MyAppExtension
    arguments: [ "@app.myservice" ]
    tags:
       - { name: twig.extension }

so I defined explicitly the argument

app.myservice.config:
     class: AppBundle\Service\MyServiceConfig
     public: true
     arguments: 
         $key:  "%app_key%" #defined in parameter.yml

it still does not work

This is how the MyServiceConfig Class looks like:

 class MyServiceConfig implements MyServiceConfigInterface {

    /**
     * @var string
     */
    private $key;

   public function __construct($key){
    $this->key= $key;
 }
}

MyAppExtension Class:

/**
 * The MyAppExtension class
 */
 class MyAppExtension extends \Twig_Extension
  {
  /**
   * @var MyServiceConfigInterface $key
   */
  private $key;

  public function __construct(MyServiceConfigInterface $key){
    $this->key= $key;
  }
}

The solution provided here did not help either since i have my service.yml inside app/config/services.yml

Upvotes: 3

Views: 2706

Answers (1)

Cerad
Cerad

Reputation: 48865

So I got bored. Update your app/config/services.yml file to:

#app.myservice.config:
AppBundle\Service\MyServiceConfig:
#    public: true
    arguments:
        $key: "%key%"

#app.myservice:
#    class: AppBundle\Service\MyAppService
#    arguments: ["@app.myservice.config"]
#    public: true

Your TwigExtension typehints against MyAppServiceInterface. So autowire looks in the container for a service with an id of MyAppServiceInterface. It does not look at the class parameter at all. Now in your case you have MyAppService implementing your interface and autowire is smart enough to recognize that there is one and only one implementation of your interface.

Be a bit more robust to explicitly alias your implementation to the interface to prevent problems if you ever decided to add another implementation. Not strictly necessary in this case.

AppBundle\Service\MyServiceConfig:
    { $key: "%key%" } # Just showing off here

AppBundle\Service\MyServiceConfigInterface: '@AppBundle\Service\MyServiceConfig'

And one more unrelated thing: Don't call your twig extension class AppBundleExtension. Seems like you are mixing up twig extensions with bundle extensions. Two different concepts. Does not really matter but it may be confusing down the line.

Upvotes: 2

Related Questions