Symfony4使用外部类库作为服务

时间:2018-09-04 10:45:29

标签: php symfony dependency-injection

我有一个小的外部库,可以公开许多类。

在我的symfony4项目中,我想从供应商处声明我的班级,以作为autowire和public的服务。 因此,我在composer中包含了我的库,并将这样的psr配置添加到composer.json中:

"autoload": {
        "psr-4": {
            "App\\": "src/",
            "ExternalLibrary\\": "vendor/external-library/api/src/"
        }
    }

之后,我尝试将我的services.yaml更改为symfony,如下所示:

ExternalLibrary\:
    resource: '../vendor/external-library/api/src/*'
    public: true
    autowire: true

如果我启动测试或运行应用程序,则会向我返回此错误:

Cannot autowire service "App\Domain\Service\MyService": argument "$repository" of method "__construct()" references interface "ExternalLibrary\Domain\Model\Repository" but no such service exists. You should maybe alias this interface to the existing "App\Infrastructure\Domain\Model\MysqlRepository" service.

如果我在services.yaml中声明该接口,则可以正常工作:

ExternalLibrary\Domain\Model\Lotto\Repository:
    class: '../vendor/external-library/api/src/Domain/Model/Repository.php'
    public: true
    autowire: true

但是我有很多类,并且我不想声明每个类,如何在不声明每个服务的情况下修复services.yaml?

谢谢

3 个答案:

答案 0 :(得分:1)

您需要手动创建服务: 我没有测试它,但是它应该看起来像这样

services.yaml

Some\Vendor\:
    resource: '../vendor/external-library/api/src/*'
    public: true # should be false

Some\Vendor\FooInterface:
    alias: Some\Vendor\Foo # Interface implementation

Some\Vendor\Bar:
    class: Some\Vendor\Bar
    autowire: true

php

<?php

namespace Some\Vendor;

class Foo implements FooInterface
{

}

class Bar
{
    public function __construct(FooInterface $foo)
    {

    }
}

更准确地说,您应该有类似的东西

ExternalLibrary\Domain\Model\Repository:
    alias: App\Infrastructure\Domain\Model\MysqlRepository

答案 1 :(得分:0)

让我们以 Dompdf 为例:

当您尝试在操作控制器或服务方法中添加Type-hint Dompdf时,将发生错误,提示无法进行自动装配,因为 Dompdf 外部 PHP库

因此,要解决此问题,我们将通过添加此简短配置

对我们的services.yaml文件进行一些更改
Dompdf\: #Add the global namespace
   resource: '../vendor/dompdf/dompdf/src/*' #Where can we find your external lib ?
   autowire: true  #Turn autowire to true

将以上示例应用于所有外部PHP库:)

仅此而已!

答案 2 :(得分:0)

我遇到了同样的问题,有人给了我这个解决方案,对我来说很好用:

Use an external repository with symfony4 trouble with autoload and parameters

为防万一,我在这里通过用户@DasBen复制其他解决方案:

我认为您不必分别导入每个服务。您已经通过“ Puc \ SapClient”部分完成了此操作。

问题可能是您正在导入模型,而不应该导入。

在symfony示例项目中,有以下部分:“ services.yaml”:

# makes classes in src/ available to be used as services
  # this creates a service per class whose id is the fully-qualified class name
  App\:
    resource: '../src/*'
    exclude: '../src/{Bundle,DependencyInjection,Entity,Model,Migrations,Tests,Kernel.php}'

那么您应该是:

# makes classes in src/ available to be used as services
  # this creates a service per class whose id is the fully-qualified class name
  Puc\SapClient\:
    resource: '../vendor/puc/sap-client/src/*'
    exclude: ''../vendor/puc/sap-client/src/{Entity,Model,"etc."}'

“等”。将成为服务中不需要的一切。