maxxtweek
@maxxtweek
Начинающий бекэнд разработчик

Как правильно назвать сервис в Symfony для вызова в разных местах?

Всем привет.
Есть Класс
BaseBuilder
public function __construct(string $file, array $mapping)
    {
        $this->file = $file;
        $this->mapping = $mapping;
    }


Этот класс я использую в двух разных сервисах, которые назвал по разному.
FirstBuilder:
    public: true
    autowire: false
    class: App\Builder\BuilderBase
    arguments:
      $file: '%kernel.project_dir%/public/files/first.xml'
      $mapping: '%first.mapping%'
 TwoBuilder:
    public: true
    autowire: false
    class: App\Builder\BuilderBase
    arguments:
      $file: '%kernel.project_dir%/public/files/two.xml'
      $mapping: '%two.mapping%'


Так же есть фабрика, в которую как раз таки и прокидывается один из сервисов
App\Factory\Point\Test:
    public: true
    class: App\Factory\Point\Test
    arguments:
      $creator: '@App\Creator\TestCreator'
      $sender: '@App\Sender\TestSender'
      $builder: '@FirstBuilder'


НО выдает ошибку :С
Cannot autowire service "App\Builder\BuilderBase": argument "$file" of method "__construct()" is type-hinted "string", you should configure its value explicitly.
В чем ошибка?
Документация и гугл не помог :С

Заранее благодарю за ответы.
  • Вопрос задан
  • 468 просмотров
Пригласить эксперта
Ответы на вопрос 1
skobkin
@skobkin
Гентушник, разработчик на PHP и Symfony.
Что такое "не работает"?
Ну и вы же сами в примерах выше выключили автовайринг. Например, тут:
TwoBuilder:
    public: true
    ###
    autowire: false
    ###
    class: App\Builder\BuilderBase
    arguments:
      $file: '%kernel.project_dir%/public/files/two.xml'
      $mapping: '%two.mapping%'

Я, конечно, могу ошибаться, но подстановка аргументов по именам - это, вроде как, часть автовайринга.

Благодарю за ответ, но все равно такая же ошибка :С

Ещё есть мысль, что, скорее всего, ваши сервисы FirstBuilder и TwoBilder (правильно: SecondBilder) конфигурируются правильно (если опустить потенциальную проблему с передачей по именам без автовайринга), а ошибка конфигурации возникает именно с сервисом App\Builder\BuilderBase. Обратите внимание, что я имею в виду не класс, а именно ID сервиса. То есть, по факту у вас есть ручная конфигурация двух "виртуальных", если так выразиться сервисов и одна конфигурация дефолтного представления сервиса, которая создаётся автоматически (т.к. автовайринг и автоконфигурация включены глобально, чего вы не показали в вопросе, кстати).

Иными словами:
- Сервис FirstBuilder - валиден и конфигурируется нормально
- Сервис TwoBuilder - валиден и конфигурируется нормально
- Сервис App\Builder\BuilderBase - пытается конфигурироваться автоматически, но не может, т.к. для скалярных аргументов, массивов и всего прочего, что не сервис нужны либо биндинги дефолтных значений (см. services._defaults.bind)? Либо явная передача аргументов в написанном вами блоке конфигурации.

Так что вам, наверное, правильнее будет чтобы не выключать автовайринг глобально сделать один билдер дефолтным с ID сервиса App\Builder\BuilderBase дабы система не пыталась сконфигурировать ещё один сервис под этот класс, а второй билдер уже называть как вам угодно.

Вывод:
Читать про нововведения в DI после 3.3 (а лучше и про более поздние), осмыслять, рефакторить конфигурацию.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы