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

时间:2013-09-21 09:44:24

标签: php symfony doctrine-orm annotations

我正在尝试模仿Route Symfony注释(documentation)的行为,该注释扩展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是doctrine注释阅读器。

这不起作用,因为在AnnotatedRouteControllerLoader 中再次阅读注释会导致不同的实例,从而失去service属性。

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

1 个答案:

答案 0 :(得分:0)

Route类被声明为服务,引用doc,你可以通过控制器注入依赖项,也可以使用“setter injection”。看看这里: 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"]]