1

I have a service which injects string values from my parameters.yml.

I declared the service like so:

parameters:
    url: '%cms_url%'
    client_id: '%cms_client_id%'
    client_secret: '%cms_client_secret%'

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false

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

    api:
        class: AppBundle\Service\Api
        arguments: ['@session', '%cms_url%']
        autowire: false

    access_token_generator:
        class: AppBundle\Security\AccessTokenGenerator    
        arguments: [cms_url, cms_client_id, cms_client_secret]
        autowire: false

When I ran the app it AccessTokenGenerator throws an error saying:

Cannot autowire service argument $apiUrl must have typehint or given value directly.

This is my AccessTokenGenrator class:

class AccessTokenGenerator
{
    private $apiUrl;

    private $clientId;
    private $clientSecret;

    public function __construct(string $apiUrl, string $clientId, string $clientSecret)
    {
        $this->apiUrl = $apiUrl;
        $this->clientId = $clientId;
        $this->clientSecret = $clientSecret;
    }

    public function generateAccessToken(string $username, string $password) : ?AccessToken
    {
        $queryParams = [
            'client_id'     => $this->clientId,
            'client_secret' => $this->clientSecret,
            'grant_type'    => 'password',
            'username'      => $username,
            'password'      => $password
        ];
        $requestUrl = $this->apiUrl . '/oauth/v2/token?' . http_build_query($queryParams);

        $client = new Client();
        $request = new Request('GET', $requestUrl);
        $response = $client->send($request);

        $contents = json_decode($response->getBody()->getContents(), true);

        if (isset($contents['access_token'])) {
            $accessToken = new AccessToken();
            $accessToken->setAccessToken($contents['access_token']);
            $accessToken->setExpiresIn($contents['expires_in']);
            $accessToken->setTokenType($contents['token_type']);
            $accessToken->setScope($contents['scope']);
            $accessToken->setRefreshToken($contents['refresh_token']);

            return $accessToken;
        }
    }
}

I dont know why it proceeds to autowiring even my configuration is set to false.

Thanks!

2
  • 1
    Don't know why autowiring still is active maybe a cache issue? But you don't need to turn it off at all. You can just pass the parameter manually as named argument. Look at symfony.com/doc/current/… Commented Oct 11, 2017 at 7:20
  • Because you have marked this question as resolved, we are curious to know how you have resolved your problem Commented Oct 12, 2017 at 7:57

3 Answers 3

3

@Arno is right you can autowire a scalar if you specify exaclty the name of paramaters.

https://symfony.com/doc/current/service_container.html#service-parameters

sorry i haven't see it part before.

Sign up to request clarification or add additional context in comments.

Comments

2

The AppBundle\Security\AccessTokenGenerator service is automatically loaded with autowire: true by this declaration :

AppBundle\:
        resource: '../../src/AppBundle/*'

You can override any service that's imported by using its id (class name) below

AppBundle\Security\AccessTokenGenerator:
    arguments: ['%cms_url%', '%cms_client_id%', '%cms_client_secret%']

Warning, you have forgottent the percentage '%' for arguments. If you need a access_token_generator service, you can make an alias :

access_token_generator: '@AppBundle\Security\AccessTokenGenerator'

Final file could be :

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false

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

    api: '@AppBundle\Service\Api'
    AppBundle\Service\Api:
        arguments: {$apiUrl: '%cms_url%'}

    access_token_generator: '@AppBundle\Security\AccessTokenGenerator'
    AppBundle\Security\AccessTokenGenerator:
        arguments: ['%cms_url%', '%cms_client_id%', '%cms_client_secret%']

Documentation : manually wiring arguments

Documentation : explicitly configuring services and arguments

Comments

1

You can not autowire scalar parameter just object

see documentation

https://symfony.com/doc/current/service_container/autowiring.html#fixing-non-autowireable-arguments

5 Comments

Thanks, Just missed that part of the documentation. Thanks!
Good comment, but it does not answer the question. It is a comment, and not an answer
If he need to declare a service with a scalar argument, it should be declared at autowire false ... No ?
I don't understand you last comment. If you set autowire to false, you lose the interest of autowiring ...
this does not answer the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.