Unable to pass parameter to service in Symfony 3.3

I am use a parameter in my service with Symfony 3.3 but I keep getting the error.

Error

[Symfony\Component\DependencyInjection\Exception\AutowiringFailedException] Cannot autowire service "AppBundle\Service\ApiInterface": argument "$api_endpoint" of method "__construct()" must have a type-hint or be given a value explicitly.

config.yml

services:
app.security.login_form_authenticator:
    class: AppBundle\Security\LoginFormAuthenticator
    autowire: true
    arguments: ['@doctrine.orm.entity_manager']
app.service.api_interface:
    class: AppBundle\Service\ApiInterface
    arguments:
      $api_endpoint: "%endpoint test%"

_defaults:
    autowire: true
    autoconfigure: true
    public: false

AppBundle\:
    resource: '../../src/AppBundle/*'
    exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

AppBundle\Controller\:
    resource: '../../src/AppBundle/Controller'
    public: true
    tags: ['controller.service_arguments']

ApiInterface.php

use Unirest;

class ApiInterface
{

private $api_endpoint;

public function __construct(string $api_endpoint)
{
    $this->timeout = 1;

    echo 'form apiinterface construct: ' . $api_endpoint;

}

Any help appreciated feel like I am going round in circles in what should be a simple job!

1 answer

  • answered 2017-10-11 12:18 Arno

    The problem is that you have 2 different services :app.service.api_interface and AppBundle\Service\ApiInterface. The first is good configured, the second is not.

    If you necessarily need the app.service.api_interface service, you can change your configuration in order to have the first as an alias of the second like this :

    app.service.api_interface: '@AppBundle\Service\ApiInterface'
    AppBundle\Service\ApiInterface:
        arguments:
            $api_endpoint: "%endpoint test%"
    

    With your config, you do not configure the AppBundle\Service\ApiInterface service, but you configure the app.service.api_interface service. With my suggestion, you configure the 2 services.

    If you do not need app.service.api_interface service, you can only let one service :

    AppBundle\Service\ApiInterface:
        arguments:
            $api_endpoint: "%endpoint test%" 
    

    This declaration overrides the AppBundle\Service\ApiInterfaceservice. You can override any service that's imported by using its id (class name) below : It's preferable to move this overriding below the AppBundle\ declaration.

    Final file can be like this :

    #app/config/services.yml
    services:
        _defaults:
            autowire: true
            autoconfigure: true
            public: false
    
        AppBundle\:
            resource: '../../src/AppBundle/*'
            exclude: '../../src/AppBundle/{Entity,Repository,Tests}'
    
        AppBundle\Controller\:
            resource: '../../src/AppBundle/Controller'
            public: true
            tags: ['controller.service_arguments']
    
        app.security.login_form_authenticator: '@AppBundle\Security\LoginFormAuthenticator'
            # autowire: true #Optional, already set in _defaults
            # arguments: ['@doctrine.orm.entity_manager'] # Optional because of autowiring
    
        app.service.api_interface: '@AppBundle\Service\ApiInterface' 
        AppBundle\Service\ApiInterface:
            arguments:
                $api_endpoint: "%endpoint test%"
    

    Documentation : manually wiring arguments

    Documentation : explicitly configuring services and arguments

    In addition, I suggest you to remove the space of the parameter name %endpoint test% (and rename it to %endpoint_test% for example)