这是一个例子:
我标记了实现DriverInterface’app.driver’的所有服务,并将其绑定到$drivers变量.
在其他一些服务中,我需要获取所有标记为“app.driver”的驱动程序并实例化并仅使用其中的少数几个.但是需要什么驱动力是动态的.
services.yml
_defaults:
autowire: true
autoconfigure: true
public: false
bind:
$drivers: [!tagged app.driver]
_instanceof:
DriverInterface:
tags: ['app.driver']
其他一些服务:
/**
* @var iterable
*/
private $drivers;
/**
* @param iterable $drivers
*/
public function __construct(iterable $drivers)
{
$this->drivers = $drivers;
}
public function getDriverByClassName(string $className): DriverInterface
{
????????
}
因此,实现Driver接口的服务被注入$this-> drivers param作为可迭代结果.我只能通过它们进行预告,但随后将实例化所有服务.
有没有其他方法来注入这些服务以通过类名从中获取特定服务而无需实例化其他服务?
附:我知道有可能将这些驱动程序公开并使用容器代替,但是如果可以采用其他方法,我希望避免将硬币注入服务中.
解决方法:
ServiceLocator将允许按名称访问服务,而无需实例化其余部分.它确实需要编译器通过,但它不是很难设置.
use Symfony\Component\DependencyInjection\ServiceLocator;
class DriverLocator extends ServiceLocator
{
// Leave empty
}
# Some Service
public function __construct(DriverLocator $driverLocator)
{
$this->driverLocator = $driverLocator;
}
public function getDriverByClassName(string $className): DriverInterface
{
return $this->driverLocator->get($fullyQualifiedClassName);
}
现在来了魔术:
# src/Kernel.PHP
# Make your kernel a compiler pass
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
class Kernel extends BaseKernel implements CompilerPassInterface {
...
# Dynamically add all drivers to the locator using a compiler pass
public function process(ContainerBuilder $container)
{
$driverIds = [];
foreach ($container->findTaggedServiceIds('app.driver') as $id => $tags) {
$driverIds[$id] = new Reference($id);
}
$driverLocator = $container->getDeFinition(DriverLocator::class);
$driverLocator->setArguments([$driverIds]);
}
并且presto.假设您修复了我可能已经介绍的任何语法错误或拼写错误,它应该可以工作.
此外,您还可以自动注册驱动程序类并删除服务文件中的instanceof条目.
# Kernel.PHP
protected function build(ContainerBuilder $container)
{
$container->registerForAutoconfiguration(DriverInterface::class)
->addTag('app.driver');
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。