1

我正在尝试使用创建服务定位器ServiceLocatorTagPass,如下所示:

use Symfony\Component\DependencyInjection;

$container = new DependencyInjection\ContainerBuilder();

$container->register('the_service')
                  ->setPublic(true)
                  ->setClass(MockService::class);

$container->register('foo')
       ->setClass(Foo::class)
       ->addTag('the_tag');

$container->register('bar')
          ->setClass(Bar::class)
          ->addTag('the_tag');

$def        = $container->getDefinition('the_service');
$serviceIds = $container->findTaggedServiceIds('the_tag');
        
$locatables = [];
foreach ($serviceIds as $serviceId => $tags) {
    $locatables[] = new DependencyInjection\Reference($serviceId);
}

$def->setArgument(0, DependencyInjection\Compiler\ServiceLocatorTagPass::register($container, $locatables));

$container->compile();

上面使用的类:

class MockService {
    public function __construct(public DependencyInjection\ServiceLocator $serviceLocator) {}
}

class Foo {}
class Bar {}

以上似乎工作正常。我看我可以$container->get('the_service')的。我可以检查这是true

$service = $container->get('the_service');
2 === \count($service->serviceLocator->getProvidedServices())

但是,如果我尝试通过服务定位器的 ID 从服务定位器获取各个服务,我什么也得不到:

$service->serviceLocator->has('foo'); // returns false
$service->serviceLocator->has('bar'); // returns false

显然我可以通过 ID'0'和获得服务'1',这不太理想:

$service->serviceLocator->get('0') instanceof Foo; // would return true :/

如何ServiceLocatorTagPass为包含的服务设置 ID 集?有可能吗?

为了方便起见,整个事情都可以在这里运行。

(以上内容已更改,因此它适合所有可以运行的脚本,但这实际上是编译器传递和该编译器传递测试的一部分)

4

1 回答 1

0

服务定位器的 id 将是传递给的数组的键ServiceLocatorTagPass::register()

由于我没有设置任何键,因此它们是0and 1

用这个改变代码:

foreach ($serviceIds as $serviceId => $tags) {
    $locatables[$serviceId] = new DependencyInjection\Reference($serviceId);
}

...解决了我的问题。

最大的努力。顶级幸福。

于 2021-08-19T10:27:08.327 回答