如何在运行时初始化Symfony服务?

问题描述 投票:0回答:1

我想要一项服务取决于某些参数,如下所示:

# services.yaml
parameters:
    schemes: '%env(json:SCHEMES)%'
    default_scheme: '%env(DEFAULT_SCHEME)%'
    active_scheme: ''

services:
    App\Service\SoapClient:
        arguments:
            $scheme: '%active_scheme%'

我这样使用这项服务:

class MyController extends AbstractController
{
    public function createClient(SoapClient $soapClient): JsonResponse
    {
        ...
        return $this->json([
            ...
        ]);
    }
}

问题是

active_scheme
可能会根据请求进行更改。所以
active_scheme
可能是
schemes
之一,具体取决于请求

我尝试通过创建事件监听器来解决它:

final class RequestListener
{
    public function __construct(
        #[Autowire(service: 'service_container')]
        private readonly ContainerInterface $container,

        #[Autowire(param: 'kernel.environment')]
        private readonly string $env
    )
    {
    }

    #[AsEventListener(event: KernelEvents::REQUEST)]
    public function onKernelRequest(RequestEvent $event): void
    {
        $schemes = $this->container->getParameter('schemes');
        $defaultScheme = $this->container->getParameter('default_scheme');

        if ($this->env === 'prod') {
            $this->container->setParameter('active_scheme', $schemes[$defaultScheme]);
        } else {
            if (!$event->getRequest()->request->has('scheme')) {
                throw new BadRequestHttpException('...');
            }
            $this->container->setParameter('active_scheme', $event->getRequest()->request->getString('scheme'));
        }
    }
}

此代码引发异常:无法在冻结的 ParameterBag 上调用 set()。

我可以从服务中删除我的 SoapClient 并将代码从上面移动到控制器,但我不喜欢这个解决方案,因为现在我需要手动创建 SoapClient 实例。

有没有办法让代码尽可能干净并允许动态实例化服务参数?

php symfony
1个回答
0
投票

不要注入该参数,而是直接从参数包中获取:

use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

class SoapClient
{
    private string $scheme;

    public function __construct(ParameterBagInterface $params)
    {
    }

    public function call(): string
    {
        // Dynamically resolved when calling this method.
        $this->scheme = $this->params->resolve('%active_scheme%');
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.