Symfony 按某个值在控制器中动态获取服务实例
我想在controller(symfony 4)中仅通过值获取一个服务实例,该值可能如下所示: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 {} 现
$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;
}
}