Symfony如何在@Route注释中内部设置服务名称


How does Symfony internally sets the service name in @Route annotation?

我正在尝试模拟Route Symfony 注解(文档)的行为,它Symfony'Component'Routing'Annotation'Route添加 service 属性进行扩展:

class Route extends BaseRoute
{
    protected $service;
    public function setService($service)
    {
        $this->service = $service;
    }
    // ...
}

它添加 service 属性,以便在控制器实际为服务时将 _controller 参数设置为 servicename:method。这是在AnnotatedRouteControllerLoader类中完成的:

protected function configureRoute(Route $route, 'ReflectionClass $class, 
    'ReflectionMethod $method, $annot)
{
    // ...
    if ($classAnnot && $service = $classAnnot->getService()) {
        $route->setDefault('_controller', $service.':'.$method->getName());
    } else {
        // Not a service ...
    }
    // ...
}

我的问题是如何/何时调用setService($service)

我尝试定义我的自定义MyCustomRoute注释(使用上面的service属性),循环每个容器服务并调用setService($serviceId)以"通知"控制器实际上是一个服务:

foreach ($container->getServiceIds() as $serviceId) {
    if ($container->hasDefinition($serviceId)) {
        $definition = $container->getDefinition($serviceId);
        $reflector = new 'ReflectionClass($definition->getClass());
        // If the service is a controller then flag it for the 
        // AnnotatedRouteControllerLoader
        if ($annot = $reader->getClassAnnotation($reflector, 
            'My'CustomAnnotations'MyCustomRoute')) {
            $annot->setServiceName($serviceId);
        }
    }
}

这里$container是Symfony服务容器,$reader是学说注释阅读器。

这是行不通的,因为AnnotatedRouteControllerLoader再次读取批注会导致不同的实例,从而丢失service属性。

我只使用路由组件(没有整个Symfony框架)。

Route 类被声明为服务,参考文档,你可以通过控制器注入依赖关系,也可以使用"setter 注入"。 看看这里:http://symfony.com/doc/current/book/service_container.html#optional-dependencies-setter-injection

因此,您可以将服务声明为:

my_custom.router:
    class:     "Acme'MyBundle'MyServices'MyRouter"
    calls:
        - [setService, ["@service_key"]]