После обновления до Symfony 7 я установил версию 5.4, и теперь мне нужно передать сервис контейнер в сервис через конструктор, но я получаю ошибку. В версии 5.4 код работал без проблем, и в файле services.yaml не потребовалось ничего прописывать – автоподстановка работала. В чем может быть ошибка в Symfony 7?
<br/> <br/>
<pre><code class="php">use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
class LoadFixtures extends Fixture
{
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
}</code></pre>
<br/> <br/>
services.yaml
<br/> <pre><code>services:
# default configuration for services in *this* file
_defaults:
autowire: true
autoconfigure: true</code></pre>
<br/> <br/>
В Symfony 7 использование контейнера напрямую в сервисах не рекомендуется, так как это нарушает принцип инъекции зависимостей и может привести к сложностям в тестировании и поддержке кода. Вместо этого, лучше использовать инъекцию конкретных зависимостей, которые вам нужны, через конструкторы или методы.
Если вы всё же хотите получить доступ к контейнеру для использования, вам необходимо зарегистрировать сервис правильно в вашем `services.yaml` и убедиться, что вы передали только те зависимости, которые вам действительно нужны.
Вот как можно переписать ваш класс, избегая передачи самого контейнера:
```php
namespace App\DataFixtures;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use App\Service\YourService;
class LoadFixtures extends Fixture
{
private $yourService;
public function __construct(YourService $yourService)
{
$this->yourService = $yourService;
}
public function load(ObjectManager $manager)
{
// Используйте $this->yourService по мере необходимости
}
}
```
В `services.yaml` не нужно ничего изменять, если `YourService` автоподставляется и правильно настроен.
Если вам действительно необходимо обратиться к контейнеру для получения других сервисов, можно сделать это через метод `container` в классах, которые имеют доступ к контейнеру, например, контроллерах. Однако максимально избегайте передачи всего контейнера, а вместо этого передавайте только необходимые сервисы через конструктор.
Если вам нужна функциональность, аналогичная контейнеру, очень важно для поддержки и простоты кода разделить зависимости и использовать их только там, где это необходимо.
То что вы хотите сделать является антипаттерном и начиная с 5.1 был помечен как Deprecated <br/> <a href="https://symfony.com/blog/new-in-symfony-5-1-deprecate-public-services-into-private-services" rel="nofollow">https://symfony.com/blog/new-in-symfony-5-1-deprec...</a> <br/> <a href="https://aksymfony.readthedocs.io/en/5.4/service_container.html#public-versus-private-services" rel="nofollow">https://aksymfony.readthedocs.io/en/5.4/service_co...</a> <br/> Оно у вас работало в 5 версии, потому что все "Deprecated" удаляются с выходом мажорной версии. <br/> <br/> Если вы всё равно хотите идти этим путём, то вам придётся это явно указывать в конфиге, либо использовать атрибуты <a href="https://symfony.com/doc/current/service_container/autowiring.html" rel="nofollow">https://symfony.com/doc/current/service_container/...</a>