Symfony4 使用外部类库作为服务
Posted
技术标签:
【中文标题】Symfony4 使用外部类库作为服务【英文标题】:Symfony4 use external class library as a service 【发布时间】: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 对接口没有多大帮助。以下面答案的最后一部分为例。 【参考方案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
【讨论】:
以上是关于Symfony4 使用外部类库作为服务的主要内容,如果未能解决你的问题,请参考以下文章