| Q | A
| ---------------- | -----
| Bug report? | yes
| Feature request? |no
| BC Break report? |no
| RFC? |no
| Symfony version | 3.3
Edit: after some more reading I believe I should just disable autowiring for the used folders (for example the Doctrine folder). I was under the impression that autowiring only was executed when a class didn't have a service yet.
Running on a default installation of Symfony 3.3, and I didn't change anything in app/config/services.yml. Even though I am running into this issue while using FOS Userbundle, I believe the issue is related to symfony itself, or I am doing something wrong.
I need a custom UserManager, so I created a class AppBundle\Doctrine\UserManager
which extends FOS\UserBundle\Doctrine\UserManager
.
The service is configured like this:
app.doctrine.manager.user_manager:
public: false
class: AppBundle\Doctrine\UserManager
arguments:
- "@fos_user.util.password_updater"
- "@fos_user.util.canonical_fields_updater"
- "@fos_user.object_manager"
- '%fos_user.model.user.class%'
In app/config I defined this:
fos_user:
db_driver: orm
firewall_name: api
user_class: AppBundle\Entity\User
from_email:
address: "%mailer_user%"
sender_name: "%mailer_user%"
service:
user_manager: 'app.doctrine.manager.user_manager'
The error:
PHP Fatal error: Uncaught Symfony\Component\DependencyInjection\Exception\AutowiringFailedException: Cannot autowire service "AppBundle\Doctrine\UserManager": argument "$class" of method "FOS\UserBundle\Doctrine\UserManager::__construct()" must have a type-hint or be given a value explicitly.
The constructor of FOS (which I originally didn't override) looks like this:
/**
* Constructor.
*
* @param PasswordUpdaterInterface $passwordUpdater
* @param CanonicalFieldsUpdater $canonicalFieldsUpdater
* @param ObjectManager $om
* @param string $class
*/
public function __construct(PasswordUpdaterInterface $passwordUpdater, CanonicalFieldsUpdater $canonicalFieldsUpdater, ObjectManager $om, $class)
{
parent::__construct($passwordUpdater, $canonicalFieldsUpdater);
$this->objectManager = $om;
$this->class = $class;
}
To me it looks like I autowiring shouldn't have done anything here, no? When I look into the compiler pass of FOSUser, they just create an alias to my own service.
For now I can resolve this problem by overriding the __construct method, and adding = ''
to the $class argument and then everything works just fine.
/**
* Constructor.
*
* @param PasswordUpdaterInterface $passwordUpdater
* @param CanonicalFieldsUpdater $canonicalFieldsUpdater
* @param ObjectManager $om
* @param string $class
*/
public function __construct(PasswordUpdaterInterface $passwordUpdater, CanonicalFieldsUpdater $canonicalFieldsUpdater, ObjectManager $om, $class = '')
{
parent::__construct($passwordUpdater, $canonicalFieldsUpdater, $om, $class);
}
your PSr-4 loading defines an autowired service with id AppBundle\Doctrine\UserManager
. your own explicit config defines a service with id app.doctrine.manager.user_manager
.
So you still have the autowired service needing some explicit config.
you have 2 choices to solve it:
AppBundle\Doctrine\UserManager
service does not get createdAppBundle\Doctrine\UserManager
as id when configuring the service explicitly, so that it overwrites the service defined by the PSR-4 import (instead of keeping both)closing since there is no bug
@stof thanks, I misinterpreted the autowiring functionality. It is solved now.
Most helpful comment
your PSr-4 loading defines an autowired service with id
AppBundle\Doctrine\UserManager
. your own explicit config defines a service with idapp.doctrine.manager.user_manager
.So you still have the autowired service needing some explicit config.
you have 2 choices to solve it:
AppBundle\Doctrine\UserManager
service does not get createdAppBundle\Doctrine\UserManager
as id when configuring the service explicitly, so that it overwrites the service defined by the PSR-4 import (instead of keeping both)