2013-03-25 12 views
8

È possibile impostare l'ID di servizio in un argomento in modo dinamico (ad esempio come un nome di classe che potrebbe essere impostato tramite parametro) in Symfony 2 (xml configs)?ID servizio dinamico in un argomento in symfony2?

La seguente non funziona

<service id="myservice" class="myservice.php"> 
    <argument type="service" id="%dynamic_service_name%" /> 
</service> 

<service id="service1" class="foobar\service1" /> 
<service id="service2" class="foobar\service1" /> 

l'idea è di impostare il parametro% dynamic_service_name% dinamicamente a "service1" o "Service2", quindi l'istanza/oggetto necessaria viene passato a myservice classe, ad esempio in Extension :: load() tramite $ container-> setParameter ('dynamic_service_name', 'service1');

Grazie mille

+0

Potresti aggiungere i parametri al codice che hai fornito. Non ci sono parametri nel codice dato. – Seer

risposta

1

Direttamente dalla documentazione di Symfony2;)

<!-- app/config/config.xml --> 
<parameters> 
    <parameter key="my_mailer.class">Acme\HelloBundle\Mailer</parameter> 
    <parameter key="my_mailer.transport">sendmail</parameter> 
</parameters> 

<services> 
    <service id="my_mailer" class="%my_mailer.class%"> 
     <argument>%my_mailer.transport%</argument> 
    </service> 
</services> 

E 'questo quello che stai cercando?

http://symfony.com/doc/current/book/service_container.html#service-parameters

Edit:

Questo è uno dei miei servizi, utilizzando un parametro. Tuttavia, è in YAML. Questo funziona bene. Come puoi vedere, sta usando il nome della classe con lo spazio dei nomi della classe nel parametro.

parameters: 
    seer_ukd_wright_gallery.gallery_helper.class: SeerUK\DWright\GalleryBundle\DependencyInjection\GalleryHelper 

services: 
    seer_ukd_wright_gallery.gallery_helper: 
     class: %seer_ukd_wright_gallery.gallery_helper.class% 
     arguments: 
      em: "@doctrine.orm.entity_manager" 
+0

sfortunatamente no, perché con questa "soluzione" ho appena passato una stringa al servizio e non un'istanza di un oggetto/servizio .. – user1826848

+0

Se stai provando con i nomi dei file php, non funzionerà ... Assicurati di utilizzare il nome della classe, con lo spazio dei nomi. Dai un'occhiata alla pagina della documentazione. Ti darò un esempio da uno dei miei servizi, è in YAML però ... – Seer

+0

ovviamente impostando dinamicamente un nome di classe tramite un parametro è possibile ma voglio impostare l'id di un servizio dinamicamente – user1826848

16

È possibile utilizzare CompilerPass:

class DynamicServiceCompilerPass implements CompilerPassInterface 
{ 
    public function process(ContainerBuilder $container) 
    { 
     $container->getDefinition('myservice') 
      ->setArguments(array(new Reference($container->getParameter('dynamic_service_name')))); 
    } 
} 

e aggiungerlo alla classe Bundle:

public function build(ContainerBuilder $container) 
{ 
    parent::build($container); 

    $container->addCompilerPass(new DynamicServiceCompilerPass()); 
} 

Follow Up:

Dal Symfony 2.4 è possibile utilizzare Expression Language così:

<services> 
    <service id="myservice" class="My\Service"> 
     <argument type="expression">service(container.hasParameter('dynamic_service_name') ? parameter('dynamic_service_name') : 'default_service_name')</argument> 
    </service> 
</services> 
+0

La soluzione è bella! Grazie! :) –

0

Questo è più o meno come si può fare usando il contenitore stesso come fabbrica. È quindi possibile definire il proprio 'dynamic_service_name' come service1 o service2 e verrà caricato in quel servizio. (XML per una fabbrica è leggermente diversa in 2.6, ma dovrebbe funzionare lo stesso)

<service id="service1" class="foobar\service1" /> 
<service id="service2" class="foobar\service1" /> 

<service id="some.service" class="foobar\service1" 
      factory-service="service_container" 
      factory-method="get"> 
     <argument>%dynamic_service_name%</argument> 
    </service> 

<service id="myservice" class="myservice.php"> 
    <argument type="service" id="some.service" /> 
</service> 
0

aggiunta alla risposta di Peter Fox', ecco l'equivalente in YAML:

some.service: 
    class: Foobar\Service1 
    factory_service: service_container 
    factory_method: get 
    arguments: 
     - %dynamic_service_name% 
myservice: 
    class: MyService 
    arguments: 
     - @some.service 

ci sono due piccole differenze nei come sono specificate le classi dei due servizi. Non ho familiarità con l'uso di nomi di file come classi e foobar\service1 non è compatibile con PSR, quindi li ho sostituiti.

1

È possibile leggere un parametro nella definizione del servizio, con la funzione parameter() e creare un servizio con la funzione service(). Così si può creare un servizio dinamico

Nella tua parameters.yml

parameters: 
     dynamic_service_name: mydynamicservice 

nei vostri servizi.yml

myservice: 
     class: My\Service 
     arguments:['@=service(parameter("dynamic_service_name"))'] 
Problemi correlati