2015-12-10 22 views
6

Ho un FooService che recupera alcuni dati da un altro servizio di configurazione.Come iniettare il risultato del metodo di un servizio come argomento per un altro servizio?

Ho il servizio di configurazione poiché la configurazione è diversa a seconda dei dati della richiesta. Il servizio di configurazione ha iniettato il RequestStack e crea l'array di configurazione pertinente.

mio FooService appare come segue:

class Foo 
{ 
    private $config; 

    /** 
    * @param Config $config 
    */ 
    public function __construct(Config $config) { 
     $this->config = $config->getData(); 
    } 
} 

Eppure, invece di iniettare del servizio, preferisco di iniettare solo il risultato della chiamata al metodo getData, in quanto è più semplice per i test di unità. Non ho bisogno di prendere in giro la configurazione, posso solo passare un array.

Il mio attuale service.yml ha una definizione simile:

config: 
    ... 

foo: 
    class: Kopernikus\LeBundle\Service\Foo 
    arguments: 
     - @config 

Ho provato a cambiare la mia definizione foo come per i metodi di fabbrica tramite:

foo: 
    class: Kopernikus\LeBundle\Service\Foo 
    arguments: 
     - [@config, getData] 

ancora anche questo inietta l'intero servizio.

Come iniettare il risultato del metodo di un servizio come argomento per un altro servizio?

risposta

8

È possibile raggiungere questo obiettivo con il linguaggio delle espressioni (New in Symfony 2.4)

Come descritto nel documento here si può fare qualcosa come ad esempio:

config: 
    ... 

foo: 
    class: Kopernikus\LeBundle\Service\Foo 
     arguments: ["@=service('config').getData()"] 

Spero che questo help

+1

Le parentesi sono troppo qui, poiché iniettano una matrice di un array. Giusto '" @ = servizio ('config'). GetData() "' sufficiente. =) – k0pernikus

+0

È stato spostato [qui] (http://symfony.com/doc/3.3/service_container/expression_language.html) dalla versione ** 3 ** – Trix

0

Stai praticamente chiedendo un contenitore per l'iniezione di dipendenza. Puoi crearne uno che ha una semplice funzione (ad esempio) get() che restituisce una nuova istanza di Foo? È possibile definirlo per creare nuovi oggetti dopo ogni chiamata di get() o più di un singleton che restituisce sempre lo stesso oggetto (memorizzandolo in una variabile statica privata).

ad esempio,

<?php 
class FooContainer implements YourContainerInterface { 
    public static function get() { 
     // Config logic here 
     return new Foo($config); 
    } 
} 
+0

Sembra che OP stia chiedendo come iniettare il resu Si tratta di una chiamata di metodo a un servizio anziché al servizio stesso, anche se non capisco chiaramente perché vorrebbero farlo, quindi potrei fraintendere il problema. –

+0

@JeremyHarris Ho aggiornato il caso d'uso per il motivo per cui voglio farlo. – k0pernikus

+0

L'unico modo per passare una funzione in questo modo è tramite stringa, che in realtà non è l'ideale poiché non è possibile eseguire alcun tipo di controllo su di esso (senza utilizzare la logica aggiuntiva). Il modo appropriato per farlo in PHP è tramite oggetto contenitore. – Ian

Problemi correlati