我有一个基本的控制器类,它有一些所有子控制器都将使用的实用程序方法。到目前为止,它有3个依赖项,但将来可能会有更多。因此,我现在有一个问题,IMO,每当我想向子控制器添加依赖项时,都会有过多的DI指令。
abstract class BaseController extends AbstractController
{
public function __construct(
protected readonly SerializerInterface $serializer,
protected readonly ValidatorInterface $validator,
private readonly ResponseGenerator $responseGenerator,
) {
}
...
}
class ChildController extends BaseController
{
// All the parent class injections are required in all child classes.
public function __construct(
SerializerInterface $serializer,
ValidatorInterface $validator,
ResponseGenerator $responseGenerator,
private readonly SomeRepository $someRepository,
... insert any other child controller-specific dependencies here.
) {
parent::__construct($serializer, $validator, $responseGenerator);
}
...
}
我尝试在基本控制器中使用$this->container->get('serializer')
,但这不起作用,因为AbstractController::$container
是通过注入定义的,但没有构造函数,所以调用parent::__construct()
是不可能的。此外,它不会给予validator
,所以即使它起作用,也只能解决部分问题。
我试着寻找一个我可以使用的属性,例如。
abstract class BaseController extends AbstractController
{
#[Inject]
protected readonly SerializerInterface $serializer;
#[Inject]
protected readonly ValidatorInterface $validator;
但是没有找到类似的东西(PHP-DI有,但Symfony没有)。
有没有办法以某种方式摆脱子控制器中的重复依赖关系?
1条答案
按热度按时间pdtvr36n1#
你需要的是service subscribers
Symfony中的控制器在扩展
AbstractController
时是服务订阅者,这意味着它们注入了一个小容器,其中包含一些常见的服务,如twig,序列化器,表单生成器等。如果你想让你的子控制器使用一些“公共”服务,你可以通过覆盖父控制器中的getSubscribedServices()来扩展列表。或者如果你的控制器没有扩展Symfony提供的默认值,你只需要实现你自己的:
如果你的控制器是一个服务(我猜已经是了),Symfony将使用setter注入来注入控制器中的容器。
代码如下所示: