【问题标题】:Symfony4 use external class library as a serviceSymfony4 使用外部类库作为服务
【发布时间】:2019-02-09 09:08:06
【问题描述】:

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

在我的 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?

谢谢

【问题讨论】:

  • 不确定加载整个目录是否是个好主意。这可能会对容器构建过程产生影响。无论如何,对于构造函数参数中的每个接口,您都需要手动声明一个类或别名。
  • 好的,你能举一个你认为应该解决的例子吗?谢谢@FabienPapet
  • 似乎您的第一种方法应该有效。回到它然后运行“bin/console debug:container”,看看你是否有任何 ExternalLibrary 服务。您可能必须注释掉 App 命名空间的行,才能克服原来的错误。
  • @Cerad 问题是我正在自动装配一个接口,并且应该使用别名声明例如
  • 我很确定您需要将接口 ExternalLibrary\Domain\Model\Repository 设为 ExternalLibrary\Domain\Model\Lotto\Repository 的别名。我们的cmets越过了。 autowire 对接口没有多大帮助。以下面答案的最后一部分为例。

标签: php symfony dependency-injection


【解决方案1】:

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

Use an external repository with symfony4 trouble with autoload and parameters

我在这里复制用户@DasBen的另一个解决方案以防万一:

我认为您不必单独导入每个服务。您已经在使用“Puc\SapClient”部分这样做了。

问题可能是您正在导入不应导入的模型。

在 symfony 示例项目中有这部分 vor "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."}'

“等等”将是所有不需要的服务。

【讨论】:

    【解决方案2】:

    我们以 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 库:)

    就是这样!

    【讨论】:

      【解决方案3】:

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

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多