2012-09-25 14 views
6

lo tanto, aquí es un controlador que acabo de construcción:Tratar de definir mis reguladores como el servicio en Symfony2 - los argumentos que nunca se pasan al constructor

namespace MDP\API\ImageBundle\Controller; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\JsonResponse; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; 

class RetrieverController { 

    private $jsonResponse; 

    private $request; 

    public function __construct(JsonResponse $jsonResponse, Request $request) { 
     $this->jsonResponse = $jsonResponse; 
     $this->request = $request; 
    } 

    /** 
    * @Route("/image/{amount}") 
    * @Template("MDPAPIImageBundle:Retriever:index.json.twig") 
    */ 
    public function retrieve($amount) 
    { 
    } 
} 

Quiero hacer este trabajo como un servicio de controlador , para usar DependencyInjection. Por lo tanto, aquí está mi services.xml archivo:

<?xml version="1.0" ?> 

<container xmlns="http://symfony.com/schema/dic/services" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> 


    <services> 
     <service id="mdpapi_image.json_response" class="Symfony\Component\HttpFoundation\JsonResponse" /> 
     <service id="mdpapi_image.request" class="Symfony\Component\HttpFoundation\Request" /> 
     <service id="mdpapi_image.controller.retriever" class="MDP\API\ImageBundle\Controller\RetrieverController"> 
      <argument type="service" id="mdpapi_image.json_response" /> 
      <argument type="service" id="mdpapi_image.request" /> 
     </service> 
    </services> 
</container> 

Sin embargo, cuando intento ejecutar mi controlador, siempre me esta excepción:

capturable error fatal: Argumento 1 pasó a MDP \ API \ ImageBundle \ Controller \ RetrieverController :: __ construct() debe ser una instancia de Symfony \ Component \ HttpFoundation \ JsonResponse, none given, llamado en /home/steve/projects/APIs/app/cache/dev/jms_diextra/controller_injectors/MDPAPIImageBundleControllerRetrieverController.php on line 13 y definido en /home/steve/projects/ImageAPAP/ImageBundle/Controller/RetrieverController.php línea 13

Cuando estoy en el modo de desarrollador, veo que Symfony genera este archivo en los archivos almacenados en caché ...

class RetrieverController__JMSInjector 
{ 
    public static function inject($container) { 
     $instance = new \MDP\API\ImageBundle\Controller\RetrieverController(); 
     return $instance; 
    } 
} 

¿Cómo puedo hacerlo de modo que los argumentos se añaden correctamente al controlador, como se especifica en mi archivo services.xml?

Respuesta

0

parece que se olvidó de escribir un extension class que loads su archivo services.xml:

namespace MDP\API\ImageBundle\DependencyInjection; 

use Symfony\Component\HttpKernel\DependencyInjection\Extension; 
use Symfony\Component\DependencyInjection\ContainerBuilder; 
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; 
use Symfony\Component\Config\FileLocator; 

class ImageExtension extends Extension 
{ 
    /** 
    * @param array $configs 
    * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container 
    */ 
    public function load(array $configs, ContainerBuilder $container) 
    { 
     $loader = new XmlFileLoader(
      $container, 
      new FileLocator(__DIR__.'/../Resources/config') 
     ); 

     $loader->load('services.xml'); 
    } 
} 
+0

Sí, tengo este código de extensión también. Todavía no funciona ... – iRESTful

1

Por lo tanto, me fijo mi problema. Tuve que dejar de usar Anotaciones en mi controlador y cambié mi enrutamiento.yml así que escribo las rutas directamente.

image_retrieve: 
    pattern: /image/{amount} 
    defaults: { _controller: mdp_api_image_retriever_retrieve:retrieve } 
    requirements: 
     _method: GET 

Eso solucionó todo el problema. El problema con las anotaciones es que en esta clase de JMS (\ DiExtraBundle \ HttpKernel \ ControllerResolver) en la línea 90, en el núcleo de Symfony, se ve este núcleo:

// If the cache warmer tries to warm up a service controller that uses 
// annotations, we need to bail out as this is handled by the service 
// container directly. 
if (null !== $metadata->getOutsideClassMetadata()->id 
       && 0 !== strpos($metadata->getOutsideClassMetadata()->id, '_jms_di_extra.unnamed.service')) { 
      return; 
} 

A continuación, en la línea 69, que trata de llamar al método call_user_func de los datos devueltos, que era nulo.

En otras palabras, usar Anotación y crear sus Controladores como Servicio NO funciona en conjunto. He perdido 4 horas de depuración este tema, así que espero que esto podría ayudar a alguien en el futuro :)

+0

Ver mi respuesta, puede usar anotaciones – Matt

3

Sólo encontró la respuesta a su pregunta, espero que esto le ayuda (u otras personas que se encuentran a esta pregunta)

<?php 
namespace MDP\API\ImageBundle\Controller; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\JsonResponse; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; 

/** 
* @Route("/image", service="mdpapi_image.controller.retriever") 
*/ 
class RetrieverController { 

    private $jsonResponse; 

    private $request; 

    public function __construct(JsonResponse $jsonResponse, Request $request) { 
     $this->jsonResponse = $jsonResponse; 
     $this->request = $request; 
    } 

    /** 
    * @Route("/{amount}") 
    * @Template("MDPAPIImageBundle:Retriever:index.json.twig") 
    */ 
    public function retrieve($amount) 
    { 
    } 
} 
Fuentes:

http://richardmiller.co.uk/2011/10/25/symfony2-routing-to-controller-as-service-with-annotations/

http://symfony.com/doc/current/cookbook/controller/service.html

Cuestiones relacionadas