从服务到另一个服务的依赖注入不起作用 symfony 5
Dependency injection from service to another service not working symfony 5
我正在尝试为 "Newuser" 服务配置依赖注入。为了以后不依赖mysql,做的是创建一个"mysqlService"服务,用"persist"方法实现接口
在控制器中,我通过注入 "DatabaseServiceInterface" 和另一个服务 "UserPasswordEncoderInterface" 的接口在其构造函数中实例化用例 "NewUser"。
由于 symfony 抱怨,它无法正常工作,因为 "NewUser doesn't receive anything as parameter"(当服务应该被自动注入时)。
文件是:
数据库服务接口:
<?php
namespace App\Application\Infraestructure\DatabaseService;
Interface DatabaseServiceInterface
{
public function persist(Object $ormObject):void;
}
Mysql服务:
<?php
namespace App\Application\Infraestructure\DatabaseService;
use Doctrine\ORM\EntityManagerInterface;
class MysqlService implements DatabaseServiceInterface
{
private $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
public function persist(Object $ormObject):void{
$this->entityManager->persist($ormObject);
$this->entityManager->flush();
}
}
注册控制器:
<?php
namespace App\Controller;
use App\Application\AppUseCases\User\NewUser\NewUserRequest;
use App\Application\Domain\User\User;
use App\Application\Infraestructure\DatabaseService\
DatabaseServiceInterface;
use App\Application\Infraestructure\DatabaseService\MysqlService;
use App\Form\RegistrationFormType;
use App\Application\Infraestructure\User\UserAuthenticator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\
UserPasswordEncoderInterface;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use App\Application\AppUseCases\User\NewUser\NewUser;
class RegistrationController extends AbstractController
{
/**
* @Route("/register", name="app_register")
*/
public function register(Request $request,
UserPasswordEncoderInterface $passwordEncoder,
GuardAuthenticatorHandler $guardHandler, UserAuthenticator
$authenticator): Response
{
$user = new User();
$form = $this->createForm(RegistrationFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$newUserRequest = new NewUserRequest();
$newUserRequest->email = $form->get('email')->getData();
$newUserRequest->user = $user;
$newUserRequest->password = $form->get('plainPassword')-
>getData();
$newUser = new NewUser();
$newUser->execute($newUserRequest);
// do anything else you need here, like send an email
return $guardHandler->authenticateUserAndHandleSuccess(
$user,
$request,
$authenticator,
'main' // firewall name in security.yaml
);
}
return $this->render('registration/register.html.twig', [
'registrationForm' => $form->createView(),
]);
}
}
使用新用户
<?php
namespace App\Application\AppUseCases\User\NewUser;
use App\Application\Infraestructure\DatabaseService\
DatabaseServiceInterface;
use Symfony\Component\Security\Core\Encoder\
UserPasswordEncoderInterface;
class NewUser {
private $databaseService;
private $passwordEncoder;
public function __construct(
DatabaseServiceInterface $databaseService,
UserPasswordEncoderInterface $passwordEncoder
) {
$this->databaseService = $databaseService;
$this->passwordEncoder = $passwordEncoder;
}
public function execute(NewUserRequest $userRegisterRequest) {
//Encode the plain password
$userRegisterRequest->user->setPassword(
$this->passwordEncoder->encodePassword(
$userRegisterRequest->user,
$userRegisterRequest->password
)
);
$userRegisterRequest->user->setEmail($userRegisterRequest->email);
$userRegisterRequest->user->setRoles(array_unique(['ROLE_USER']));
//crear servicio para mysql
$this->databaseService->persist($userRegisterRequest->user);
}
}
Services.yaml
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where
the app is deployed
#https://symfony.com/doc/current/best_practices/
configuration.html#application-related-configuration
parameters:
locale: en
availableLocales:
- es
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your
services.
autoconfigure: true # Automatically registers your services as
commands, event subscribers, etc.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified
class name
App\:
resource: '../src/*'
exclude:
'../src/{DependencyInjection,Entity,
Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller
#class
App\Application\Infraestructure\DatabaseService\
DatabaseServiceInterface:
App\Application\Infraestructure\DatabaseService
尽管 symfony 没有抛出任何错误,因为看起来配置很好,但它仍然无法工作。它在执行用例时抛出的错误如下:
Too few arguments to function App\Application\AppUseCases\User\NewUser\NewUser::__construct(), 0 passed in /var/www/symfony/src/Controller/RegistrationController.php on line 33 and exactly 2 expected
您不是从容器中检索 NewUser
class,而是手动实例化它,因此没有发生依赖关系解析,服务也没有接收任何依赖关系。您应该将服务注入控制器以进行依赖项解析,或者在实例化时显式传递参数。
public function register(Request $request,
UserPasswordEncoderInterface $passwordEncoder,
GuardAuthenticatorHandler $guardHandler,
UserAuthenticator $authenticator,
NewUser $newUser): Response
{
//...
$newUserRequest = new NewUserRequest();
//...
// $newUser = new NewUser(); // Not passing The Database or PasswordEncoder dep
$newUser->execute($newUserRequest);
//...
}
我正在尝试为 "Newuser" 服务配置依赖注入。为了以后不依赖mysql,做的是创建一个"mysqlService"服务,用"persist"方法实现接口
在控制器中,我通过注入 "DatabaseServiceInterface" 和另一个服务 "UserPasswordEncoderInterface" 的接口在其构造函数中实例化用例 "NewUser"。
由于 symfony 抱怨,它无法正常工作,因为 "NewUser doesn't receive anything as parameter"(当服务应该被自动注入时)。
文件是:
数据库服务接口:
<?php
namespace App\Application\Infraestructure\DatabaseService;
Interface DatabaseServiceInterface
{
public function persist(Object $ormObject):void;
}
Mysql服务:
<?php
namespace App\Application\Infraestructure\DatabaseService;
use Doctrine\ORM\EntityManagerInterface;
class MysqlService implements DatabaseServiceInterface
{
private $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
public function persist(Object $ormObject):void{
$this->entityManager->persist($ormObject);
$this->entityManager->flush();
}
}
注册控制器:
<?php
namespace App\Controller;
use App\Application\AppUseCases\User\NewUser\NewUserRequest;
use App\Application\Domain\User\User;
use App\Application\Infraestructure\DatabaseService\
DatabaseServiceInterface;
use App\Application\Infraestructure\DatabaseService\MysqlService;
use App\Form\RegistrationFormType;
use App\Application\Infraestructure\User\UserAuthenticator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\
UserPasswordEncoderInterface;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use App\Application\AppUseCases\User\NewUser\NewUser;
class RegistrationController extends AbstractController
{
/**
* @Route("/register", name="app_register")
*/
public function register(Request $request,
UserPasswordEncoderInterface $passwordEncoder,
GuardAuthenticatorHandler $guardHandler, UserAuthenticator
$authenticator): Response
{
$user = new User();
$form = $this->createForm(RegistrationFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$newUserRequest = new NewUserRequest();
$newUserRequest->email = $form->get('email')->getData();
$newUserRequest->user = $user;
$newUserRequest->password = $form->get('plainPassword')-
>getData();
$newUser = new NewUser();
$newUser->execute($newUserRequest);
// do anything else you need here, like send an email
return $guardHandler->authenticateUserAndHandleSuccess(
$user,
$request,
$authenticator,
'main' // firewall name in security.yaml
);
}
return $this->render('registration/register.html.twig', [
'registrationForm' => $form->createView(),
]);
}
}
使用新用户
<?php
namespace App\Application\AppUseCases\User\NewUser;
use App\Application\Infraestructure\DatabaseService\
DatabaseServiceInterface;
use Symfony\Component\Security\Core\Encoder\
UserPasswordEncoderInterface;
class NewUser {
private $databaseService;
private $passwordEncoder;
public function __construct(
DatabaseServiceInterface $databaseService,
UserPasswordEncoderInterface $passwordEncoder
) {
$this->databaseService = $databaseService;
$this->passwordEncoder = $passwordEncoder;
}
public function execute(NewUserRequest $userRegisterRequest) {
//Encode the plain password
$userRegisterRequest->user->setPassword(
$this->passwordEncoder->encodePassword(
$userRegisterRequest->user,
$userRegisterRequest->password
)
);
$userRegisterRequest->user->setEmail($userRegisterRequest->email);
$userRegisterRequest->user->setRoles(array_unique(['ROLE_USER']));
//crear servicio para mysql
$this->databaseService->persist($userRegisterRequest->user);
}
}
Services.yaml
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where
the app is deployed
#https://symfony.com/doc/current/best_practices/
configuration.html#application-related-configuration
parameters:
locale: en
availableLocales:
- es
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your
services.
autoconfigure: true # Automatically registers your services as
commands, event subscribers, etc.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified
class name
App\:
resource: '../src/*'
exclude:
'../src/{DependencyInjection,Entity,
Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller
#class
App\Application\Infraestructure\DatabaseService\
DatabaseServiceInterface:
App\Application\Infraestructure\DatabaseService
尽管 symfony 没有抛出任何错误,因为看起来配置很好,但它仍然无法工作。它在执行用例时抛出的错误如下:
Too few arguments to function App\Application\AppUseCases\User\NewUser\NewUser::__construct(), 0 passed in /var/www/symfony/src/Controller/RegistrationController.php on line 33 and exactly 2 expected
您不是从容器中检索 NewUser
class,而是手动实例化它,因此没有发生依赖关系解析,服务也没有接收任何依赖关系。您应该将服务注入控制器以进行依赖项解析,或者在实例化时显式传递参数。
public function register(Request $request,
UserPasswordEncoderInterface $passwordEncoder,
GuardAuthenticatorHandler $guardHandler,
UserAuthenticator $authenticator,
NewUser $newUser): Response
{
//...
$newUserRequest = new NewUserRequest();
//...
// $newUser = new NewUser(); // Not passing The Database or PasswordEncoder dep
$newUser->execute($newUserRequest);
//...
}