Symfony 4 - Сервис удален или встроен, хотя он общедоступен

Я пытаюсь перенести приложение SF 3.3 в SF 4 с его новой структурой каталогов и всем остальным.

Я борюсь с этим исключением:

Служба или псевдоним simplethings_entityaudit.reader были удалены или встроены при компиляции контейнера. Вы должны либо сделать его общедоступным, либо прекратить использование контейнера напрямую и вместо этого использовать внедрение зависимостей.

(Эта услуга предоставляется из внешнего пакета, расположенного в / vendor).

Тем не менее, когда я bin/console debug:container simplethings_entityaudit.reader вы увидите, что служба существует и является общедоступной:

Information for Service "simplethings_entityaudit.reader"
=========================================================

 ----------------- -------------------------------------- 
  Option            Value                                 
 ----------------- -------------------------------------- 
  Service ID        simplethings_entityaudit.reader       
  Class             SimpleThings\EntityAudit\AuditReader  
  Tags              -                                     
  Public            yes                                   
  Synthetic         no                                    
  Lazy              no                                    
  Shared            yes                                   
  Abstract          no                                    
  Autowired         no                                    
  Autoconfigured    no                                    
  Factory Service   simplethings_entityaudit.manager      
  Factory Method    createAuditReader                     
 ----------------- -------------------------------------- 

Эта служба в настоящее время вызывается в одной из моих собственных с $this->container->get('simplethings_entityaudit.reader').

Я также попытался ввести SimpleThings\EntityAudit\AuditReader в свой конструктор службы, но вот что я получил:

Аргумент «$ auditReader» метода «__construct ()» ссылается на класс «SimpleThings \ EntityAudit \ AuditReader», но такой службы не существует. Он не может быть автоматически зарегистрирован, потому что он из другого корневого пространства имен.

Когда я добавляю это в свой services.yaml, он работает, но мне не нужно этого делать:

SimpleThings\EntityAudit\AuditReader:
    alias: simplethings_entityaudit.reader

Любые идеи?


person Ben    schedule 24.01.2018    source источник
comment
Это нормально с псевдонимом, что вы можете сделать, когда внешний пакет не предоставляет псевдоним для совместимости с Symfony 4. Если это ваш пакет, добавьте в него псевдоним.   -  person malcolm    schedule 24.01.2018
comment
так как это не ясно видно из ответа: добавьте свойство public:true в качестве родственника к псевдониму   -  person john Smith    schedule 25.02.2019


Ответы (3)


В моем случае ошибка появляется в модульном тесте.

У меня была одна служба, которую нельзя было загрузить в тестах (Symfony 4.2), в то время как все остальные службы в моем проекте работали хорошо.

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

Вывод: если у вас есть модульный тест и вы хотите протестировать свою службу, вы также должны предоставить контроллер, в который внедряется служба, в противном случае он будет недоступен в контейнере тестовой службы. Также может помочь явная конфигурация службы.

person Hendrik Pilz    schedule 25.03.2019
comment
Это, по крайней мере, частично неверно. Добавление контроллера, вероятно, просто пометило службу как используемую, поэтому она не была удалена во время сброса контейнера. - person Jean; 10.05.2019

В Symfony 4.0 любая служба, которая не указывает ее видимость, является частной, https://github.com/symfony/symfony/pull/24238.

Насколько я понимаю, упомянутый вами сервис не определяет видимость: https://github.com/simplethings/EntityAuditBundle/blob/1.0/src/SimpleThings/EntityAudit/Resources/config/auditable.xml#L23-L26, так что это, вероятно, причина вашего исключения.

Если служба simplethings_entityaudit.reader не может быть подключена автоматически (и это, вероятно, связано с тем, что она использует заводскую службу), вы можете внедрить ее в свою службу, указав на нее обозначение @simplethings_entityaudit.reader следующим образом: https://symfony.com/doc/current/service_container.html#services-manual-wire-args, что-то вроде этого:

services:
    My\Service:
        arguments:
            $auditReader: @simplethings_entityaudit.reader
person Edi Modrić    schedule 24.01.2018
comment
Привет, Эди, я действительно это знаю, но по какой-то причине служба помечается как общедоступная при выполнении debug:container. Когда вы говорите, что это, вероятно, связано с использованием фабричной службы, где это поведение задокументировано? Никогда об этом не слышал. Спасибо Бен - person Ben; 25.01.2018
comment
О, я предположил, что вывод команды debug:container был из Symfony 3.3. В Symfony 4.0 я не уверен, почему он должен отображаться как общедоступный в выводе. Что касается автоматического подключения и заводского обслуживания, я не знаю, документировано ли оно где-либо, это было обоснованное предположение, потому что это кажется веской причиной, по которой его нельзя было подключать автоматически, поскольку система автоматического подключения не знает, как построить сервис . Еще одна потенциальная причина может заключаться в том, что для этой службы автосоединение просто не включено (поскольку оно не настроено в его файле конфигурации), но это всего лишь предположения. - person Edi Modrić; 26.01.2018
comment
На самом деле это была ошибка, исправленная в последней версии Symfony 4.0.x. - person Ben; 11.04.2018
comment
Да, как вы предлагаете и опубликованные вами документы, одним из вариантов является настройка видимости службы с помощью public: true - person FantomX1; 06.06.2020
comment
Я просто добавляю этот документ, потому что он полезен в данном случае: symfony.com/doc/current/service_container/ - person vincent PHILIPPE; 20.08.2020

В нашем случае мы создали services_test.yml вместе с .env.test с APP_ENV, установленным для тестирования.

затем в этом services_test.yml мы поместили

услуги: _defaults: public: true

поэтому по умолчанию все сервисы общедоступны

не забудьте указать свои .env и .env.test. Мне часто приходится это делать, и я перезапускаю свою виртуальную машину.

person Solber    schedule 18.12.2020