I need help for my project. I try to inject Entity Manager inside my service (SendInBlueService) call with messenger, but DependencyInjection can't find doctrine.orm.entity_manager.
My test route
#[Route('api/testSendInBlue', name: 'testsendinblue')]
public function testMessenger(AsyncMethodService $asyncMethodService): Response
{
$asyncMethodService->async_low_priority(
SendInBlueService::class,
'confirmationMail',
[
$this->getUser()->getId()
]
);
return new Response('Test OK');
}
My AsyncMethodService
<?php
namespace App\Service\Messenger;
use Symfony\Component\Messenger\MessageBusInterface;
class AsyncMethodService
{
private MessageBusInterface $messageBus;
public function __construct(MessageBusInterface $messageBus)
{
$this->messageBus = $messageBus;
}
public function async_low_priority(string $serviceName, string $methodName,array $params = [])
{
$this->messageBus->dispatch(new ServiceMethodCallMessageLowPriority(
$serviceName,
$methodName,
$params
)
);
}
public function async_medium_priority(string $serviceName, string $methodName,array $params = [])
{
$this->messageBus->dispatch(new ServiceMethodCallMessageMediumPriority(
$serviceName,
$methodName,
$params
)
);
}
public function async_high_priority(string $serviceName, string $methodName,array $params = [])
{
$this->messageBus->dispatch(new ServiceMethodCallMessageHighPriority(
$serviceName,
$methodName,
$params
));
}
}
My ServiceMethodCallMessageLowPriority exactly same for High and Medium
<?php
namespace App\Service\Messenger;
class ServiceMethodCallMessageLowPriority extends ServiceMethodCallMessage
{
}
My ServiceMethodCallMessage
<?php
namespace App\Service\Messenger;
class ServiceMethodCallMessage
{
private string $serviceName;
private string $methodName;
private array $params;
public function __construct(string $serviceName, string $methodName, array $params = [])
{
$this->serviceName = $serviceName;
$this->methodName = $methodName;
$this->params = $params;
}
/**
* @return string
*/
public function getServiceName(): string
{
return $this->serviceName;
}
/**
* @return string
*/
public function getMethodName(): string
{
return $this->methodName;
}
/**
* @return array
*/
public function getParams(): array
{
return $this->params;
}
}
My MessengerHandle
<?php
namespace App\Service\Messenger;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
#[AsMessageHandler]
class ServiceMethodCallHandler extends AbstractController
{
private string $path;
public function __construct(string $path)
{
$this->path = $path;
}
public function __invoke(
ServiceMethodCallMessageLowPriority |
ServiceMethodCallMessageMediumPriority |
ServiceMethodCallMessageHighPriority $message
)
{
$containerBuilder = new ContainerBuilder();
$loader = new YamlFileLoader($containerBuilder, new FileLocator($this->path));
$loader->load('services.yaml');
$callable = [
$containerBuilder->get($message->getServiceName()),
$message->getMethodName()
];
call_user_func_array($callable,$message->getParams());
}
}
My Service Send In Blue
<?php
namespace App\Service;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
class SendInBlueService
{
private string $SEND_IN_BLUE_API_KEY;
private EntityManagerInterface $entityManager;
public function __construct(
string $SEND_IN_BLUE_API_KEY,
EntityManagerInterface $entityManager
)
{
$this->SEND_IN_BLUE_API_KEY = $SEND_IN_BLUE_API_KEY;
$this->entityManager = $entityManager;
}
public function confirmationMail(int $userId)
{
dd($this->entityManager);
$user = $this->entityManager->getRepository(User::class)->find($userId);
dd($user);
}
}
My config/services.yaml
parameters:
SEND_IN_BLUE_API_KEY: '%env(SEND_IN_BLUE_API_KEY)%'
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.
App\:
resource: '../src/'
exclude:
- '../src/Entity/'
- '../src/Kernel.php'
- '../src/DependencyInjection/'
# Messenger Declaration Service
App\Service\Messenger\ServiceMethodCallHandler:
arguments: ['%kernel.project_dir%/config']
App\Service\SendInBlueService:
class: App\Service\SendInBlueService
arguments: ['%env(SEND_IN_BLUE_API_KEY)%','@doctrine.orm.entity_manager']
And for finish my error:
I try get EntityManager with ContainerBuilder inside my service, But i have a same error.
I think i have a problem because messenger use other kernel instance, and inside this instance, the DependencyInjection don't have load all bundles.
If someone has an idea. Thanks you
CodePudding user response:
I found auto-wiring / dependency injection via using aliases always very confusing (what is visible and what is hidden, blahblah), and have usually opted to use default parameter bindings instead:
https://symfony.com/doc/current/service_container.html#binding-arguments-by-name-or-type
Using this method, you would remove the service from the services.yaml entirely (since all parameters will be known) and instead use
services:
_defaults:
bind:
string $SEND_IN_BLUE_API_KEY: '%env(SEND_IN_BLUE_API_KEY)%'
If in fact the doctrine bundle is missing from your loaded kernel, you have to find a way to add it.
CodePudding user response:
Could you please change this:
App\Service\SendInBlueService:
class: App\Service\SendInBlueService
arguments: ['%env(SEND_IN_BLUE_API_KEY)%','@doctrine.orm.entity_manager']
By this:
App\Service\SendInBlueService:
arguments:
$SEND_IN_BLUE_API_KEY: '%env(SEND_IN_BLUE_API_KEY)%'
As services are autowired.