[Symfony 4] Vanuit Command een Service zonder autowire

Pagina: 1
Acties:

Onderwerpen

Vraag


Acties:
  • +1 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 18:59

Matis

Rubber Rocket

Topicstarter
Beste PRGers,

Ik ben me aan het verdiepen in Symfony 4 (4.2 om precies te zijn). Ik heb met Symfony 3 gewerkt, maar wil graag verder met Symfony 4.

Om spelenderwijs met Symfony 4 in aanraking te komen, heb ik een toepassing bedacht. Er wordt een lijst met namen aangeleverd, deze wordt ingelezen en voor al deze namen wordt een naamkaartje gegenereerd.
Ieder naamkaartje komt dan weer op een PDF (A4 formaat) terecht waaruit ze met 8 (A7) gesneden zullen worden.

Het wordt een CLI applicatie, dus (nog) geen frontend / Controller.

Op dit moment ben ik op het punt beland waar ik een CreateCardsCommand heb gemaakt welke in de CardCreator service de create() functie moet aanroepen. De CardCreator heeft een NameProvider referentie vanwaar de namen aangeleverd worden.
Daarnaast heb ik nog een lijstje met parameters waarmee de Services gevuld (kunnen) worden.

Hierbij het overzicht van mijn Services:
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
parameters:

services:
  _defaults:
    autowire: true      # Automatically injects dependencies in your services.
    autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

  App\:
    resource: '../src/*'
    exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

  App\Controller\:
    resource: '../src/Controller'
    tags: ['controller.service_arguments']

  provider.name:
    class: App\Service\ProviderImplementation\NameProvider
    arguments:
      - "%name_file%"

  creator.card:
    class: App\Service\CreatorImplementation\CardCreator
    arguments:
      - "@provider.name"

Daarnaast heb ik de volgende parameters.yml file:
YAML:
1
2
3
parameters:
  files_directory: "%application_root%/var/files"
  name_file: "%files_directory%/names.txt"

Ik heb de volgende dingen geprobeerd:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
final class CreateCardsCommand extends Command
{

    protected static $defaultName = 'app:create-cards';

    /** @var ContainerInterface */
    private $container;

    public function __construct(CardCreator $container, ?string $name = null)
    {
        parent::__construct($name);
        $this->container = $container;
    }
/*... */
}

Dit resulteert in de volgende foutmelding
$ php bin/console app:create-cards

In DefinitionErrorExceptionPass.php line 54:
                                                                                                                                                                                                                                            
  Cannot autowire service "App\Service\ProviderImplementation\NameProvider": argument "$filename" of method "App\Service\Provider\AbstractFileProvider::__construct()" is type-hinted "string", you should configure its value explicitly.  

Ik snap de reden van de foutmelding, ik weet alleen niet hoe op te lossen.


PHP:
1
2
3
4
final class CreateCardsCommand extends ContainerAwareCommand
{
/* ... */
}

ContainerAwareCommand is deprecated. Symfony adviseert zelf om over te stappen op autowiring... Daar ben ik juist mee bezig.


Als laatste heb ik geprobeerd de Container zelf er uit te peuteren:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    /**
     * @param InputInterface  $input
     * @param OutputInterface $output
     * @return int|null
     */
    protected function execute(InputInterface $input, OutputInterface $output): ?int
    {
        if ($this->getApplication()->getKernel()->getContainer()->has(ServiceName::CREATOR_CARD) === false) {
            $output->writeln(\sprintf('The Service %s could not be found. Exiting!', ServiceName::CREATOR_CARD));

            return 1;
        }
        /** @var CardCreator $cardCreatorService */
        $cardCreatorService = $this->getContainer()->get(ServiceName::CREATOR_CARD);
        $cardCreatorService->create();

        $output->writeln('Success');

        return 0;
    }

Dit resulteert in de melding
$ php bin/console app:create-cards
The Service creator.card could not be found. Exiting!

Dat vind ik vreemd, waarom kan creator.card nu ineens niet gevonden worden, terwijl hij wel in het Symfony Ecosysteem gevonden kan worden met autowiring

Even een lijstje met softwareversies:
  • Symfony 4.2.2 (env: dev, debug: true)
  • PHP 7.2.14 (cli) (built: Jan 11 2019 01:35:56) ( NTS )
Dit alles draait op Docker, zowel op Linux als op Windows.

Wie kan me helpen?

Alvast bedankt _O_

Matis

Edit: Nog wat (bruikbare) debug logging vanuit de console:
$ php bin/console debug:autowiring 

Autowirable Types
=================

 The following classes & interfaces can be used as type-hints when autowiring:
 
 App\Service\Creator\CreatorInterface (App\Service\CreatorImplementation\CardCreator)
 
 App\Service\Provider\ProviderInterface (App\Service\ProviderImplementation\NameProvider)

$ php bin/console debug:container creator.card

Information for Service "creator.card"
======================================

 ---------------- ----------------------------------------------- 
  Option           Value                                          
 ---------------- ----------------------------------------------- 
  Service ID       creator.card                                   
  Class            App\Service\CreatorImplementation\CardCreator  
  Tags             -                                              
  Public           yes                                            
  Synthetic        no                                             
  Lazy             no                                             
  Shared           yes                                            
  Abstract         no                                             
  Autowired        yes                                            
  Autoconfigured   yes                                            
 ---------------- ----------------------------------------------- 

[ Voor 18% gewijzigd door Matis op 14-01-2019 12:08 ]

If money talks then I'm a mime
If time is money then I'm out of time

Beste antwoord (via Matis op 14-01-2019 13:01)


  • Merethil
  • Registratie: December 2008
  • Laatst online: 20:35
Matis schreef op maandag 14 januari 2019 @ 12:08:
Fuuuuuuuuuu, nu zie ik het probleem }:|
public staat niet op true
YAML:
1
2
3
4
5
  creator.card:
    class: App\Service\CreatorImplementation\CardCreator
    public: true
    arguments:
      - "@provider.name"

Problem solved *O*

Edit; Ik kan mijn eigen antwoord niet als beste markeren :+
Wie wil met de eer strijken? Dan kan dit topic naar de krochten van GoT afzakken ;w
Je moet public even op true zetten :+

Alle reacties


Acties:
  • +2 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 18:59

Matis

Rubber Rocket

Topicstarter
Fuuuuuuuuuu, nu zie ik het probleem }:|
public staat niet op true
YAML:
1
2
3
4
5
  creator.card:
    class: App\Service\CreatorImplementation\CardCreator
    public: true
    arguments:
      - "@provider.name"

Problem solved *O*

Edit; Ik kan mijn eigen antwoord niet als beste markeren :+
Wie wil met de eer strijken? Dan kan dit topic naar de krochten van GoT afzakken ;w

[ Voor 21% gewijzigd door Matis op 14-01-2019 12:09 ]

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • Beste antwoord
  • +3 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 20:35
Matis schreef op maandag 14 januari 2019 @ 12:08:
Fuuuuuuuuuu, nu zie ik het probleem }:|
public staat niet op true
YAML:
1
2
3
4
5
  creator.card:
    class: App\Service\CreatorImplementation\CardCreator
    public: true
    arguments:
      - "@provider.name"

Problem solved *O*

Edit; Ik kan mijn eigen antwoord niet als beste markeren :+
Wie wil met de eer strijken? Dan kan dit topic naar de krochten van GoT afzakken ;w
Je moet public even op true zetten :+