1

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

我有以下概念:

  • 实体:标准主义实体
  • 资源:描述资源的类,包括目标实体和可用镜头。
  • Lens:有一个方法apply(Request $request, QueryBuilder $qb)可以让你修改QueryBuilder基于Request.

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

尝试1:直接注入Lenses资源

项目资源.php

<?php

class ProjectResource
{
    protected $lenses = [];

    public function __construct(
        ProjectRepository $repository,
        LensInterface $activeProjectLens,
        LensInterface $starredProjectLens
    ) {
        $this->lenses = [
            $activeProjectLens,
            $starredProjectLens
        ];
    }

    public function getLenses() {
        return $this->lenses;
    }
}

这样做的缺点是每个Lens服务都是实例化的,需要手动定义

尝试 2:注入标记Lenses到资源中

在我的services.yaml标签中,服务并将它们作为参数分配给资源:

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

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

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

项目资源.php

<?php

class ProjectResource
{
    protected $lenses = [];

    public function __construct(
        ProjectRepository $repository,
        iterable $lenses
    ) {
        $this->lenses = $lenses;
    }

    public function getLenses() {
        return $this->lenses;
    }
}

这种方法的缺点是每个Lens服务和资源都必须被标记并且不能是自动配置的服务。

**尝试 3:添加编译器通道 **

我试图将该process()方法添加到,Kernel但我并没有走得太远。


我的目标是以某种方式定义服务列表Resource并将它们注入。这有什么既定的模式吗?

4

1 回答 1

2

您使用标签的方法似乎不错。Symfony 提供了一种自动将标签添加到实现某个接口的类的方法:基于接口的服务配置

要使用它,您必须执行以下操作:

  1. 如果您还没有,请创建一个接口(例如App\Lens\LensInterface)并让您的镜头类实现该接口。
  2. 在您的services.yaml文件中添加此配置:
services:
    // ...

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

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

    // ...

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

于 2018-08-22T12:29:48.793 回答