动态延迟加载服务

时间:2018-08-22 04:39:23

标签: symfony symfony4 symfony-dependency-injection

观看Laravell Nova演示文稿后,我想在自己的应用程序中创建与Lenses类似的功能。

我有以下概念:

  • 实体:标准主义实体
  • 资源:一个描述资源的类,其中包括目标实体和可用的透镜。
  • 镜头:具有方法 { A: { isAvailable : true} , VV: { isAvailable : false} , B45: { isAvailable : null} } ,该方法可让您基于apply(Request $request, QueryBuilder $qb)来修改QueryBuilder

目标是将所有Request定义为服务,然后以某种方式将它们分配给Lenses。这是我要解决的问题。

尝试1:将Resource直接注入资源

ProjectResource.php

Lenses

缺点是每个<?php class ProjectResource { protected $lenses = []; public function __construct( ProjectRepository $repository, LensInterface $activeProjectLens, LensInterface $starredProjectLens ) { $this->lenses = [ $activeProjectLens, $starredProjectLens ]; } public function getLenses() { return $this->lenses; } } 服务都被实例化,需要手动定义

尝试2:将标记为Lens的标签注入资源

在我的Lenses标签中,将服务指定为资源的参数:

services.yaml

ProjectResource.php

  App\Lens\ActiveProjectLens:
    tags: ['resource.project.lens']

  App\Lens\StarredProjectLens:
    tags: ['resource.project.lens']

  App\Resource\ProjectResource:
    arguments:
      $lenses: !tagged resource.project.lens

这种方法的缺点是每个<?php class ProjectResource { protected $lenses = []; public function __construct( ProjectRepository $repository, iterable $lenses ) { $this->lenses = $lenses; } public function getLenses() { return $this->lenses; } } 服务都必须标记资源,并且资源不能是自动配置的服务。

**尝试3:添加编译器密码**

我试图将Lens方法添加到process()中,但是我对此并没有太过了解。


我的目标是在Kernel中定义服务列表,并注入它们。有没有确定的模式?

1 个答案:

答案 0 :(得分:2)

您使用标记的方法似乎不错。 Symfony提供了一种将标签自动添加到实现特定接口的类的方法:Interface-based service configuration

要使用该功能,您必须执行以下操作:

  1. 如果您还没有一个接口,请创建一个接口(例如protected $table = 'admin'; ),然后让镜头类实现该接口。
  2. 在您的App\Lens\LensInterface文件中,添加以下配置:
services.yaml

然后,每个实现LensInterface的类都将注入到ProjectResource中,而不必显式配置每个镜头。