Symfony4 use external class library as a service

佐手、 提交于 2020-07-18 10:42:52

问题


I have a little external library that expose many classes.

Into my symfony4 project I would like to declare my class from vendor, as a service with autowire and public. So I have include my library with composer and add psr configuration like this into composer.json:

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

After that I have tried to change my services.yaml into symfony like this:

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

If I launch tests or run the application returns me this error:

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.

If I declare into services.yaml the interface this works fine:

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

But I have many classes and I don't want to declare each class, how can I fix services.yaml without declare every single service?

Thanks


回答1:


You need to create services by hand: I did not test it but it should look like this

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)
    {

    }
}

To be more precise you should have something like

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



回答2:


Let's take Dompdf as an example :

When you try to add type-hint Dompdf in your action controller or service method , an error will be occurred saying that auto-wiring isn't possible because Dompdf is an external PHP library

So to solve this problem we'll make a little change in our services.yaml file by adding this short config

Dompdf\: #Add the global namespace
   resource: '../vendor/dompdf/dompdf/src/*' #Where can we find your external lib ?
   autowire: true  #Turn autowire to true

Apply the above example to all external PHP libs :)

That's all !




回答3:


I had the same problem and someone gave me this solution, which works fine for me:

Use an external repository with symfony4 trouble with autoload and parameters

I copy the other solution by user @DasBen here just in case:

I think that you don't have to import each service separately. Your are already doing that with the "Puc\SapClient" part.

The problem could be that you are importing your models, which should not be imported.

In the symfony example project there is this part 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}'

Then your part would be:

# 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."}'

"etc." Would be everything that is not needed as service.



来源:https://stackoverflow.com/questions/52164486/symfony4-use-external-class-library-as-a-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!