Reputation: 340
After updating I have this deprecation:
Since symfony/dependency-injection 5.1: The "Symfony\Component\DependencyInjection\ContainerInterface" autowiring alias is deprecated. Define it explicitly in your app if you want to keep using it. It is being referenced by the "App\Service\ImportService" service.
Here is my ImportService:
<?php
namespace App\Service;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ImportService
{
private $doctrine;
private $em;
public function __construct(ContainerInterface $container)
{
$this->doctrine = $container->get('doctrine'); //needed for database queries
$this->em = $this->doctrine->getManager(); //needed for database queries
}
/** more methods here **/
}
So how exactly do I make it explicit? I googled a bit and I think that I have to add it to my services.yml
file somehow. But I am unsure how + do I have to do it for every Service class?
Upvotes: 12
Views: 12675
Reputation: 48865
I just created a new 5.1 app and did not get the deprecation. Symfony is really discouraging the injection of the global container. So I am not surprised it is being deprecated.
To fix the message, all you need to do is to explicitly define the ContainerInterface
alias:
# services.yml or yaml
services:
Symfony\Component\DependencyInjection\ContainerInterface: '@service_container'
That should do the trick. However, since you appear to be moving to 5.1 then you should start refactoring your code and only inject what a particular class needs. It is not mandatory but will save you from problems down the line:
class ImportService
{
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em
}
Upvotes: 21
Reputation: 897
As already apposed by the original answer, the correct way is to only inject the services you really need.
But in case you are extending on already existing code and the existing code changes with a new update and you want to allow backwards-compatibility, it is sometimes easier and more effective to use the ContainerInterface
instead.
As some developers also prefer XML over YAML, here are both solutions:
services.yml (if you use yaml)
services:
Symfony\Component\DependencyInjection\ContainerInterface: '@service_container'
services.xml (if you use XML)
<?xml version="1.0" ?>
<container
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"
>
<services>
<service
id="Symfony\Component\DependencyInjection\ContainerInterface"
alias="service_container"
/>
</services>
</container>
Upvotes: 1
Reputation: 24280
While other answers with injecting container will work as a quick solution, it's contra the point of this deprecation - to remove all container use from PHP code.
AFAIK Symfony, this will be more and more strict in the future, so you'll have to come back to the code and refactor it anyway.
If you want to make your code future proof, refactor to constructor injection:
<?php
namespace App\Service;
use Doctrine\DBAL\Connection;
use Doctrine\ORM\EntityManagerInterface;
final class ImportService
{
private Connection $connection;
private EntityManagerInterface $entityManager;
public function __construct(
Connection $connection,
EntityManagerInterface $entityManager
) {
$this->connection = $connection;
$this->entityManager = $entityManager;
}
/** more methods here **/
}
Upvotes: 6
Reputation: 316
You must define the '@service_container' argument in your service.yaml.
# services.yml or yaml
services:
Symfony\Component\DependencyInjection\ContainerInterface: '@service_container'
Namespace\ImportService:
arguments:
- '@service_container'
Then you can use the ContainerInterface as constructor parameter.
Upvotes: 4