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 AppServiceMessenger;
use SymfonyComponentMessengerMessageBusInterface;
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 AppServiceMessenger;
class ServiceMethodCallMessageLowPriority extends ServiceMethodCallMessage
{
}
My ServiceMethodCallMessage
<?php
namespace AppServiceMessenger;
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 AppServiceMessenger;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentDependencyInjectionContainerBuilder;
use SymfonyComponentMessengerAttributeAsMessageHandler;
use SymfonyComponentConfigFileLocator;
use SymfonyComponentDependencyInjectionLoaderYamlFileLoader;
#[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 AppService;
use AppEntityUser;
use DoctrineORMEntityManagerInterface;
use SymfonyComponentConfigFileLocator;
use SymfonyComponentDependencyInjectionContainerBuilder;
use SymfonyComponentDependencyInjectionLoaderYamlFileLoader;
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
AppServiceMessengerServiceMethodCallHandler:
arguments: ['%kernel.project_dir%/config']
AppServiceSendInBlueService:
class: AppServiceSendInBlueService
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
3
Answers
I found issue,
My first try on my ServiceMethodCallHandler is :
But ive got error.
I finish by build new container inside __invoke method. This build i can call my service but i create another error. With @Cerad message i understood that it was a mistake to create a new Container inside invoke. I restart to my first error.
I finish by find issue with add public inside service.yaml
Thank you all
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
If in fact the doctrine bundle is missing from your loaded kernel, you have to find a way to add it.
Could you please change this:
By this:
As services are autowired.