Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Symfony 按某个值在控制器中动态获取服务实例_Symfony_Service - Fatal编程技术网

Symfony 按某个值在控制器中动态获取服务实例

Symfony 按某个值在控制器中动态获取服务实例,symfony,service,Symfony,Service,我想在controller(symfony 4)中仅通过值获取一个服务实例,该值可能如下所示: $provider='youtube' 这就是我的设置: Class videoProvider { //Here I have all common methods for all services } Class YoutubeService extends videoProvider {} Class OtherVideoService extends videoProvider {} 现

我想在controller(symfony 4)中仅通过值获取一个服务实例,该值可能如下所示:
$provider='youtube'

这就是我的设置:

Class videoProvider {
//Here I have all common methods for all services
}

Class YoutubeService extends videoProvider {}

Class OtherVideoService extends videoProvider {}
现在的问题是如何做这样的事情。如果
$provider='youtube'
然后使用YouTube服务
新建YouTube服务()
继续。但如果服务不存在呢?然后呢


这可能吗?

$this->container->has('my-service-name')
$this->container->get('my-service-name')
在控制器中可能就是您想要的。我的服务名称是您在服务配置中提供的服务名称,并确保您的服务是公共的

示例配置()

然后在控制器或任何容器感知类中:()


$this->container->has('my-service-name')
和控制器中的
$this->container->get('my-service-name')
可能就是您想要的。我的服务名称是您在服务配置中提供的服务名称,并确保您的服务是公共的

示例配置()

然后在控制器或任何容器感知类中:()


你可以这样做

  • 创建一个名为Provider的文件夹
  • 创建一个界面,例如,
    VideoProviderInterface
    ,并放入文件夹中
  • 向界面添加方法
    getProviderName():string
  • 创建提供者并将其放入文件夹中,然后实现该接口
  • 向您的services.yaml添加
    \u instanceof:
    选项,并向您的界面添加一些标记
  • 从services.yaml中的
    App\:
    选项中排除提供商文件夹
  • 创建类,
    ProviderManager
    并插入服务定位器
您可以找到更多信息

服务.亚马尔

_instanceof:
    App\Provider\VideoProviderInterface:
        tags: ['app.provider']

App\Provider\:
    resource: '../../src/Provider/*'

App\Provider\ProviderManager:
    arguments:
        - !tagged_locator { tag: 'app.provider', default_index_method: 'getProviderName' }

App\:
    resource: '../src/*'
    exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php,Provider}'
视频提供者接口

<?php

namespace App\Provider;

interface VideoProviderInterface
{
    public function getProviderName(): string
}

您可以这样做

  • 创建一个名为Provider的文件夹
  • 创建一个界面,例如,
    VideoProviderInterface
    ,并放入文件夹中
  • 向界面添加方法
    getProviderName():string
  • 创建提供者并将其放入文件夹中,然后实现该接口
  • 向您的services.yaml添加
    \u instanceof:
    选项,并向您的界面添加一些标记
  • 从services.yaml中的
    App\:
    选项中排除提供商文件夹
  • 创建类,
    ProviderManager
    并插入服务定位器
您可以找到更多信息

服务.亚马尔

_instanceof:
    App\Provider\VideoProviderInterface:
        tags: ['app.provider']

App\Provider\:
    resource: '../../src/Provider/*'

App\Provider\ProviderManager:
    arguments:
        - !tagged_locator { tag: 'app.provider', default_index_method: 'getProviderName' }

App\:
    resource: '../src/*'
    exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php,Provider}'
视频提供者接口

<?php

namespace App\Provider;

interface VideoProviderInterface
{
    public function getProviderName(): string
}

到目前为止您尝试了什么?为什么不将所有服务注入某种工厂?到目前为止,您尝试了什么?为什么不将所有服务注入某种工厂?
<?php

namespace App\Provider;

use Symfony\Component\DependencyInjection\ServiceLocator;

class ProviderManager
{
    /**
     * @var ServiceLocator
     */
    private $serviceLocator;

    public function __construct(ServiceLocator $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
    }

    public function findByName(string $name): ?VideoProviderInterface
    {
        return $this->serviceLocator->has($name) ? $this->serviceLocator->get($name) : null;
    }    
}