Инъекция зависимости от службы в другую службу не работает symfony 5 - PullRequest
0 голосов
/ 12 апреля 2020

Я пытаюсь настроить внедрение зависимостей для службы "Newuser". Чтобы не зависеть от mysql в будущем, необходимо создать службу «mysqlService», которая реализует интерфейс с методом «persist».

Из контроллера я создаю экземпляр варианта использования » NewUser », который в своем конструкторе вводит интерфейс« DatabaseServiceInterface »и другой сервис« UserPasswordEncoderInterface ».

Он не работает должным образом, так как symfony жалуется, потому что «NewUser ничего не получает в качестве параметра» (когда служба должна автоматически вводиться).

Файлы:

DatabaseServiceInterface:

<?php

 namespace App\Application\Infraestructure\DatabaseService;



 Interface DatabaseServiceInterface
 {
   public function persist(Object $ormObject):void;
 }

MysqlService:

<?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();
   }

 }

RegistrationController:

<?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(),
    ]);
   }
 }

Usecas NewUser

<?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

1 Ответ

0 голосов
/ 13 апреля 2020

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

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);
       //...
}
...