Symfony 4.如何在没有依赖注入的情况下从控制器访问服务? [英] Symfony 4. How to access the service from controller without dependency injection?
问题描述
我有几个服务:DieselCaseService,CarloanCaseService LvCaseService。
I have several services: DieselCaseService, CarloanCaseService LvCaseService.
控制器决定要获取哪些服务。
The controller decides which of services to get.
$type = $quickCheck["type"];
/**
* @var $caseService \App\Service\Cases\CaseInterface
*/
$type = 'diesel; // for test purposes
$caseService = $this->get('case_service.' . $type);
服务别名的声明如下:
case_service.diesel:
alias: App\Service\Cases\DieselCaseService
public: true
class DieselCaseService implements CaseInterface
{
.
.
.
}
如果我尝试获取DieselCaseService,则会收到错误消息
If I try to get the DieselCaseService, I get an error
服务 case_service.diesel未找到:即使它存在于
应用程序的容器中,该容器也位于
$中b $ b App\Controller\Api\AccountController是一个较小的服务定位器
,仅了解学说, form.factory,
fos_rest.view_handler , http_kernel, parameter_bag,
request_stack,路由器, security.authorization_checker,
security.csrf.token_manager, security.token_storage ,序列化器,
会话,模板化和树枝服务。尝试使用dependency
注入。
Service "case_service.diesel" not found: even though it exists in the
app's container, the container inside
"App\Controller\Api\AccountController" is a smaller service locator that only knows about the "doctrine", "form.factory",
"fos_rest.view_handler", "http_kernel", "parameter_bag",
"request_stack", "router", "security.authorization_checker",
"security.csrf.token_manager", "security.token_storage", "serializer",
"session", "templating" and "twig" services. Try using dependency
injection instead.
我该怎么办?我不想将所有服务注入到控制器中。
What can I do? I don't want to inject all of the services to the controller
推荐答案
对于任何通过键来键入相同类型的多个实例在这种情况下,您可以使用自动装配阵列。
For any "multiple instances of same type by key" situation, you can use autowired array.
services:
_defaults:
autowire: true
App\:
resource: ../src
2。在构造函数中需要自动装配的数组
2. Require autowired array in Constructor
<?php
namespace App\Controller\Api;
use App\Service\Cases\DieselCaseService
final class AccountController
{
/**
* @var CaseInterface[]
*/
private $cases;
/**
* @param CaseInterface[] $cases
*/
public function __construct(array $cases)
{
foreach ($cases as $case) {
$this->cases[$case->getName()] = $cases;
}
}
public function someAction(): void
{
$dieselCase = $this->cases['diesel']; // @todo maybe add validation for exisiting key
$dieselCase->anyMethod();
}
}
3。在内核中注册编译器传递
自动连线数组功能不在Symfony内核中。感谢编译器传递。您可以编写自己的代码或使用以下代码:
3. Register compiler pass in Kernel
The autowired array functionality is not in Symfony core. It's possible thanks to compiler passes. You can write your own or use this one:
use Symplify\PackageBuilder\DependencyInjection\CompilerPass\AutowireArrayParameterCompilerPass;
final class AppKernel extends Kernel
{
protected function build(ContainerBuilder $containerBuilder): void
{
$containerBuilder->addCompilerPass(new AutowireArrayParameterCompilerPass);
}
}
就是这样! :)
我在所有项目中都使用了它,它的工作就像一个魅力。
I use it on all my projects and it works like a charm.
Read more in post about autowired arrays I wrote.
这篇关于Symfony 4.如何在没有依赖注入的情况下从控制器访问服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!